Function.prototype.call()

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

call() 方法用於呼叫一個函式,並指定函式內部 this 的值以及函式接收的引數。

試一試

function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = "food";
}

console.log(new Food("cheese", 5).name);
// Expected output: "cheese"

語法

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 = "foo";

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

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

在嚴格模式下,this 的值不會被替換,因此它將保持為 undefined

js
"use strict";

globalThis.globProp = "foo";

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

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

將方法轉換為實用函式

call() 幾乎等同於普通函式呼叫,不同之處在於 this 作為普通引數傳遞,而不是作為訪問該函式的物件的屬性傳遞。這類似於通用實用函式的工作方式:您可以使用 map(array, callback) 而不是呼叫 array.map(callback),這樣您就可以將 map 與非陣列的類陣列物件(例如 arguments)一起使用,而無需修改 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® 2026 語言規範
# sec-function.prototype.call

瀏覽器相容性

另見