Function.prototype.call()

call() 方法是 Function 实例的方法,它使用给定的 this 值和分别提供的参数调用此函数。

试试看

语法

js
call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, arg2, /* …, */ argN)

参数

thisArg

调用 func 时要使用的 this 值。如果函数不在 严格模式 中,nullundefined 将被替换为全局对象,原始值将被转换为对象。

arg1, …, argN 可选

函数的参数。

返回值

使用指定的 this 值和参数调用函数的结果。

描述

注意:此函数与 apply() 几乎相同,除了函数参数分别作为列表传递给 call(),而对于 apply(),它们在一个对象中组合,通常是一个数组——例如,func.call(this, "eat", "bananas")func.apply(this, ["eat", "bananas"])

通常,调用函数时,函数内部 this 的值是函数被访问的对象。使用 call(),您可以在调用现有函数时将任意值分配为 this,而无需首先将函数作为属性附加到对象。这允许您将一个对象的方法用作通用实用程序函数。

警告:不要使用 call() 来链接构造函数(例如,实现继承)。这将构造函数作为普通函数调用,这意味着 new.targetundefined,并且类会抛出错误,因为它们不能在没有 new 的情况下调用。请改用 Reflect.construct()extends

示例

使用 call() 调用函数并指定 this 值

在下面的示例中,当我们调用 greet 时,即使 greet 不是 obj 的方法,this 的值也会绑定到对象 obj

js
function greet() {
  console.log(this.animal, "typically sleep between", this.sleepDuration);
}

const obj = {
  animal: "cats",
  sleepDuration: "12 and 16 hours",
};

greet.call(obj); // cats typically sleep between 12 and 16 hours

使用 call() 调用函数而不指定第一个参数

如果省略第一个 thisArg 参数,它将默认为 undefined。在非严格模式下,this 值将被替换为 globalThis(类似于全局对象)。

js
globalThis.globProp = "Wisen";

function display() {
  console.log(`globProp value is ${this.globProp}`);
}

display.call(); // Logs "globProp value is Wisen"

在严格模式下,this 的值不会被替换,因此它保持为 undefined

js
"use strict";

globalThis.globProp = "Wisen";

function display() {
  console.log(`globProp value is ${this.globProp}`);
}

display.call(); // throws TypeError: Cannot read the property of 'globProp' of undefined

将方法转换为实用程序函数

call() 几乎等同于正常的函数调用,除了 this 作为普通参数传递,而不是作为函数被访问的值。这类似于通用实用程序函数的工作方式:您不是调用 array.map(callback),而是使用 map(array, callback),这允许您对不是数组的类似数组的对象(例如,arguments)使用 map,而无需修改 Object.prototype

Array.prototype.slice() 为例,您希望将其用于将类似数组的对象转换为真正的数组。您可以创建如下快捷方式

js
const slice = Array.prototype.slice;

// ...

slice.call(arguments);

请注意,您不能保存 slice.call 并将其作为普通函数调用,因为 call() 方法也会读取其 this 值,即它应该调用的函数。在这种情况下,您可以使用 bind() 来绑定 call()this 值。在以下代码段中,slice()Function.prototype.call() 的绑定版本,其 this 值绑定到 Array.prototype.slice()。这意味着可以消除额外的 call() 调用

js
// Same as "slice" in the previous example
const unboundSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(unboundSlice);

// ...

slice(arguments);

规范

规范
ECMAScript 语言规范
# sec-function.prototype.call

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参见