一、为什么需要call和apply?
在JavaScript中,函数执行时的上下文(即this
的值)默认由调用方式决定。但实际开发中,我们常需要动态改变函数的执行环境,例如让某个对象借用另一个对象的方法。这正是call
和apply
的核心价值。
1. call
方法
call
方法接受一个this
值和一个参数列表。语法如下:
functionName.call(thisArg, arg1, arg2, ...);
示例:
function greet(greeting) {
console.log(greeting + ', ' + this.name);
}
const person = { name: 'Alice' };
greet.call(person, 'Hello'); // 输出: Hello, Alice
2. apply
方法
apply
方法与call
类似,但它接受一个数组作为参数。语法如下:
functionName.apply(thisArg, [argsArray]);
示例:
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'Bob' };
greet.apply(person, ['Hi', '!']); // 输出: Hi, Bob!
二、call
与apply
的区别
-
参数传递方式:
call
接受参数列表。apply
接受一个数组。
-
使用场景:
- 当你知道参数的个数时,可以使用
call
。 - 当参数的个数不确定或者已经以数组的形式存在时,使用
apply
更为方便。
- 当你知道参数的个数时,可以使用
三、使用场景
1. 对象继承
场景:让子类继承父类的属性和方法。
function Animal(name) {
this.name = name;
}
function Dog(name) {
Animal.call(this, name); // 借用父类构造函数
}
const dog = new Dog('旺财');
console.log(dog.name); // 输出:旺财
2. 借用方法
场景:在 JavaScript 中,我们可以使用 call
或 apply
方法来借用其他对象的方法。。
const arrayLike = { 0: 'apple', 1: 'banana', length: 2 }; // 借用数组的 push 方法
Array.prototype.push.call(arrayLike, 'cherry');
console.log(arrayLike); // 输出: { 0: 'apple', 1: 'banana', 2: 'cherry', length: 3 }