Function.prototype.call()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Function
实例的 call()
方法会以给定的 this
值和逐个提供的参数调用该函数。
尝试一下
语法
call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, arg2, /* …, */ argN)
参数
thisArg
-
在调用
func
时要使用的this
值。如果函数不在严格模式下,null
和undefined
将被替换为全局对象,并且原始值将被转换为对象。 arg1, …, argN
可选-
函数的参数。
返回值
使用指定的 this
值和参数调用函数后的结果。
描述
备注:
这个函数几乎与 apply()
相同,只是函数的参数以列表的形式逐个传递给 call()
,而在 apply()
中它们被组合在一个对象中,通常是一个数组——例如,func.call(this, "eat", "bananas")
与 func.apply(this, ["eat", "bananas"])
。
通常,在调用函数时,函数内部的 this
值是访问该函数的对象。使用 call()
,你可以在调用现有函数时将任意值分配给 this
,而无需首先将函数附加到对象上作为属性。这样可以将一个对象的方法用作通用的实用函数。
警告:
不要使用 call()
来链式调用构造函数(例如,实现继承)。这会将构造函数作为普通函数调用,这意味着 new.target
的值为 undefined
,而类会抛出错误,因为它们不能在没有 new
的情况下被调用。请改用 Reflect.construct()
或 extends
。
示例
使用 call() 调用函数并指定 this 值
在下面的示例中,当我们调用 greet
时,this
的值将绑定到对象 obj
,即使 greet
不是 obj
的方法。
function greet() {
console.log(this.animal, "的睡眠时间一般在", this.sleepDuration, "之间");
}
const obj = {
animal: "猫",
sleepDuration: "12 到 16 小时",
};
greet.call(obj); // 猫 的睡眠时间一般在 12 到 16 小时 之间
使用 call() 在不指定第一个参数的情况下调用函数
如果省略第一个 thisArg
参数,则默认为 undefined
。在非严格模式下,this
值将被替换为 globalThis
(类似于全局对象)。
globalThis.globProp = "Wisen";
function display() {
console.log(`globProp 的值是 ${this.globProp}`);
}
display.call(); // 输出“globProp 的值是 Wisen”
在严格模式下,this
的值不会被替换,因此它保持为 undefined
。
"use strict";
globalThis.globProp = "Wisen";
function display() {
console.log(`globProp 的值时 ${this.globProp}`);
}
display.call(); // 抛出 TypeError: Cannot read the property of 'globProp' of undefined
将方法转换为实用函数
call()
几乎等同于普通函数调用,只是将 this
作为普通参数传入,而不是作为函数所在的对象值。这类似于通用的实用函数的工作方式:你可以使用 map(array, callback)
来代替 array.map(callback)
,这样可以避免对 Array.prototype
进行修改,还可以将 map
用于不是数组的类数组对象(例如 arguments
)。
以 Array.prototype.slice()
为例,你想要将类数组对象转换为真正的数组。你可以创建一个类似这样的快捷方式:
const slice = Array.prototype.slice;
// ...
slice.call(arguments);
请注意,你不能将 slice.call
保存并将其作为普通函数调用,因为 call()
方法也会读取它的 this
值,而这个值应该是它要调用的函数。在这种情况下,你可以使用 bind()
来绑定 call()
的 this
值。在下面的代码片段中,slice()
是一个绑定了 this
值为 Array.prototype.slice()
的 Function.prototype.call()
的版本。这意味着额外的 call()
调用可以被省略:
// 与前面示例中的“slice”相同
const unboundSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(unboundSlice);
// ...
slice(arguments);
规范
Specification |
---|
ECMAScript Language Specification # sec-function.prototype.call |
浏览器兼容性
BCD tables only load in the browser