JavaScript中call和apply方法的区别

JavaScript中call和apply方法的区别

技术背景

在JavaScript里,函数属于一等公民,可以拥有自己的方法。call()apply()Function.prototype 上的两个方法,所有函数对象都能通过原型链使用它们。这两个方法的主要作用是在调用函数时指定 this 的值,不过它们在处理函数参数的方式上存在差异。

实现步骤

1. 基本使用

  • call() 方法:需要将函数的参数逐个列出。
  • apply() 方法:要求将函数的参数放在一个数组中传入。

2. 指定 this

在调用函数时,通过这两个方法可以指定函数内部 this 的指向。

3. 根据参数情况选择方法

  • 若明确知道参数的数量,或者参数较少,使用 call() 方法更合适。
  • 若不清楚参数的数量,或者参数已经存在于一个数组或类数组对象中,使用 apply() 方法更为方便。

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 示例函数
function theFunction(name, profession) {
console.log("My name is " + name + " and I am a " + profession + ".");
}

// 直接调用
theFunction("John", "fireman");

// 使用 apply 方法
theFunction.apply(undefined, ["Susan", "school teacher"]);

// 使用 call 方法
theFunction.call(undefined, "Claude", "mathematician");

// 使用扩展运算符与 call 方法
theFunction.call(undefined, ...["Matthew", "physicist"]);

// 另一个示例
let obj = {
val1: 5,
val2: 10
};

const summation = function (val3, val4) {
return this.val1 + this.val2 + val3 + val4;
};

// 使用 apply 方法
console.log(summation.apply(obj, [2, 3]));

// 使用 call 方法
console.log(summation.call(obj, 2, 3));

最佳实践

1. 借用方法

一个对象可以借用另一个对象的方法,通过 call()apply() 方法指定 this 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var friend = {
car: false,
lendCar: function (canLend) {
this.car = canLend;
}
};

var me = {
car: false,
gotCar: function () {
return this.car === true;
}
};

console.log(me.gotCar()); // false

friend.lendCar.call(me, true);
console.log(me.gotCar()); // true

friend.lendCar.apply(me, [false]);
console.log(me.gotCar()); // false

2. 求数组的最大值和最小值

可以使用 apply() 方法将数组作为参数传递给 Math.max()Math.min() 函数。

1
2
3
var numbers = [5, 6, 2, 3, 7];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);

常见问题

1. this 值为 nullundefined 的情况

nullundefined 作为 call()apply() 的第一个参数时,全局对象会被用作 this 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
value: 10,
addValues: function () {
for (var i = 0; i < arguments.length; i++) {
this.value += arguments[i];
}
return this.value;
}
};

var f = obj.addValues;
// 以下两个语句都会将属性添加到全局对象上
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);

2. 性能差异

一般来说,如果参数已经是数组,使用 apply() 更合适;如果参数不是数组,使用 call() 可能会更快,因为 apply() 需要对数组进行评估。不过这种性能差异在不同浏览器中可能有所不同。


JavaScript中call和apply方法的区别
https://119291.xyz/posts/2025-05-09.difference-between-call-and-apply-in-javascript/
作者
ww
发布于
2025年5月9日
许可协议