在JavaScript中,`call` 和 `apply` 都是函数对象的方法,它们的主要用途是调用一个函数,并显式地设置函数内部的 `this` 值,同时允许你以数组(对于 `apply`)或参数列表(对于 `call`)的形式传递参数。
### `call` 的用法
`call` 方法的第一个参数是 `this` 值在函数运行时指定的值。其后是逗号分隔的参数列表,即传递给函数的参数。
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = {
name: 'Alice'
};
greet.call(person, 'Hello', '!'); // 输出: Hello, Alice!
### `apply` 的用法
`apply` 方法的工作方式与 `call` 类似,不同之处在于,它接受两个参数:第一个参数是 `this` 值,第二个参数是一个数组或类数组对象,其中的数组元素将作为单独的参数传递给函数。
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = {
name: 'Bob'
};
const args = ['Hi', '.'];
greet.apply(person, args); // 输出: Hi, Bob.
### 小结
- **使用场景**:当你需要动态改变函数中的 `this` 指向,并传递参数时,`call` 和 `apply` 非常有用。
- **参数传递**:`call` 直接以参数列表的形式传递,而 `apply` 通过一个数组或类数组对象传递。
- **性能差异**:在现代JavaScript引擎中,`call` 和 `apply` 的性能差异几乎可以忽略不计,但在需要传递大量参数时,使用 `apply` 可能会导致稍微的性能开销,因为它需要创建一个数组。
- **ES6 替代方案**:ES6 引入了箭头函数,它不会绑定自己的 `this`,而是捕获其所在上下文的 `this` 值,作为自己的 `this` 值。这在很多情况下可以替代 `call` 和 `apply` 的使用。