WHAT - JavaScript bind vs call vs apply(包括在箭头函数中vs在普通函数中)
文章目录
- 前言
- 一、call 和 apply 的区别(除了参数形式)
- 功能等价性
- 二、bind 与 call / apply 的区别(除了是否立即执行)
- 1. 执行时机不同
- 2. 返回值不同
- 3. 参数传递方式
- 三、底层原理上的区别(高级)
- 四、使用场景对比
- 五、总结对比表
- 在箭头函数里
- 一、箭头函数的核心特性回顾
- 二、`call`、`apply`、`bind` 在箭头函数中的表现
- 1. `call` 在箭头函数中的表现
- 2. `apply` 在箭头函数中的表现
- 3. `bind` 在箭头函数中的表现
- 三、与普通函数的对比
- 普通函数中使用 `call` / `apply` / `bind`
- 四、为什么箭头函数不能通过 `call` / `apply` / `bind` 改变 `this`?
- 五、实际开发中的建议
- 六、总结
前言
在 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