文章目录
前言
在 WHAT - JavaScript 的函数你知道多少 中我们介绍过 bind
, call
, apply
.
假如问你如下两个问题:
- apply 和 call 除了参数形式不同外还有什么区别?
- bind 和其他两个除了不会立即执行外还有什么区别?
这是一个非常好的深入问题!call
、apply
和 bind
都是 JavaScript 中用来显式设置函数中 this
值的方法,它们在功能上相似,但在使用方式、执行时机等方面存在一些关键区别。你提到的“参数形式不同”和“是否立即执行”是它们最直观的区别,但实际上它们之间还有更深层次的区别,下面我将从多个维度详细分析它们的异同。
一、call 和 apply 的区别(除了参数形式)
你提到“参数形式不同”,这是最明显的区别:
call(thisArg, arg1, arg2, ...)
:参数逐个传递。apply(thisArg, [arg1, arg2, ...])
:参数以数组(或类数组)形式传递。
但除了这个表面上的差异,它们在功能上几乎完全相同,没有其他本质上的区别。
功能等价性
无论是 call
还是 apply
,它们的核心作用都是:
- 显式绑定
this
值; - 立即调用函数;
- 传递参数给被调用的函数。
所以从功能角度来看,call
和 apply
是可以互相替代的,只是传参方式不同。
在现代 JavaScript 中,由于我们可以轻松使用展开运算符
...
,call
使用得更加普遍,因为它的写法更直观。例如:
// 使用 apply
func.apply(thisArg, [arg1, arg2]);
// 等价于使用 call + 展开运算符
func.call(thisArg, ...[arg1, arg2]);
二、bind 与 call / apply 的区别(除了是否立即执行)
你提到“bind
不会立即执行”,这确实是它最显著的特点,但它与 call
和 apply
的区别远不止这一点。
1. 执行时机不同
方法 | 是否立即执行 |
---|---|
call |
立即执行 |
apply |
立即执行 |
bind |
不立即执行,返回一个新的绑定函数 |
bind
的作用是创建一个新的函数,这个新函数的 this
值已经被固定为指定的值,而原函数并不会被调用。
function greet() {
console.log(this.name);
}
const obj = {
name: 'Alice' };
const boundGreet = greet.bind(obj); // 不执行
boundGreet(); // "Alice" (稍后执行)
2. 返回值不同
call
和apply
:直接调用函数,返回的是函数的返回值。bind
:返回一个新的函数,不会执行原函数,需要手动调用返回的函数才能执行。
funct