JavaScript 中 call、apply、bind 的区别

先理解核心:它们都是干啥的?

想象你借了一本书(函数),但你想让别人(指定对象)来读这本书的某个章节(执行函数)。

  • call:现在就让人读,你一个个告诉他读哪几页

  • apply:现在就让人读,你把页数写在一张纸条上交给他

  • bind:不急着读,先告诉他要读哪几页,给他一张"读书券",以后随时可以让他读


我的"顿悟三连"

第一层困惑:它们好像都一样?

刚学的时候,看代码:

javascript 复制代码
fn.call(obj, 1, 2, 3)
fn.apply(obj, [1, 2, 3])
fn.bind(obj, 1, 2, 3)()

内心OS:不就是参数写法不一样吗?搞这么复杂干嘛!

第二层顿悟:原来是"立即执行"和"稍后执行"的区别

直到有一次写事件监听:

javascript 复制代码
// 错误示范 ❌
button.onclick = user.sayHello.call(user);  
// 页面加载完立刻就执行了!不是我想要的

// 正确示范 ✅
button.onclick = user.sayHello.bind(user);
// 点击时才执行,完美!

这一刻我懂了:bind 是"发号施令"但不立即行动,call/apply 是"立刻执行"。

第三层顿悟:什么时候用 call,什么时候用 apply?

有次写代码找数组最大值:

javascript

javascript 复制代码
// 用 apply 多优雅
Math.max.apply(null, [1, 2, 3, 4, 5]);

// 用 call 就尴尬了
Math.max.call(null, 1, 2, 3, 4, 5); // 也行,但参数多时累死

这一刻我悟了

  • 已有数组 → apply(直接把数组扔进去)

  • 参数明确 → call(看得清楚,不用转数组)


终极对比表(我背了这一张就够了)

维度 call apply bind
执行时机 立即执行 立即执行 返回新函数,不执行
参数形式 逐个传入 a,b,c 数组传入 [a,b,c] 逐个传入,可分批传
返回值 函数结果 函数结果 新函数
经典场景 继承父类属性 找数组最大/小值 事件绑定、setTimeout
记忆口诀 C all = Comma(逗号) A pply = Array(数组) B ind = Back(稍后)

面试官最爱问的"坑"

Q:bind 之后还能改 this 吗?

javascript 复制代码
const obj = { name: 'obj' };
const obj2 = { name: 'obj2' };

function test() { console.log(this.name); }

const bound = test.bind(obj);
bound(); // 'obj'
bound.call(obj2); // 还是 'obj'!bind 绑定了就改不了了

Q:箭头函数能用 call/apply/bind 吗?

javascript 复制代码
const arrow = () => { console.log(this); };

// 没用!箭头函数的 this 是定义时就定死的
arrow.call({ name: 'test' }); // this 还是原来的

Q:手写一个 bind 看看?

javascript 复制代码
Function.prototype.myBind = function(context, ...bindArgs) {
  const fn = this;
  return function(...callArgs) {
    return fn.apply(context, [...bindArgs, ...callArgs]);
  };
};

我的最终心得

不要死记硬背,要理解设计意图

  • call:适合参数数量固定,想写得直观时

  • apply:适合参数已经在数组里,或者数量不确定时

  • bind:适合不急着执行,或者要传给事件监听、定时器时

最常用的反而是 apply (处理数组)和 bind(处理 this 指向),call 用得最少。但面试爱问区别,所以三个都得懂。

相关推荐
星辰_mya2 小时前
Fork/Join 框架与并行流:CPU 密集型的“分身术”
java·开发语言·面试
宁雨桥2 小时前
前端设计模式面试题大全
前端·设计模式
郝学胜-神的一滴2 小时前
循环队列深度剖析:从算法原理到C++实现全解析
开发语言·数据结构·c++·算法·leetcode
Via_Neo2 小时前
接雨水问题 + 输入优化
java·开发语言·算法
所谓伊人,在水一方3332 小时前
【Python数据可视化精通】第9讲 | 实时数据流可视化
开发语言·python·信息可视化·数据分析·pandas
Cg136269159742 小时前
JS函数表示
前端·html
℘团子এ2 小时前
vue3中,el-table表格固定列后出现表格线段折断的问题
javascript·vue.js·elementui
吃鱼不吐刺.2 小时前
阻塞队列。
java·开发语言
不光头强2 小时前
ArrayList知识点
java·开发语言·windows