call() 、bind()、 apply() 有哪些区别

call()、apply()、bind() 是 JavaScript 中 Function.prototype 上的三个非常重要且高频考查的方法,它们都能改变函数运行时的 this 指向,但在使用方式和效果上有明显区别。

特性call()apply()bind()
作用立即执行函数 + 改变 this立即执行函数 + 改变 this只改变 this,不立即执行,返回新函数
是否立即执行
参数传递方式逐个参数(逗号分隔)数组(或类数组)逐个参数(支持分两次传参)
第一个参数要绑定的 this(可传 null/undefined)要绑定的 this(可传 null/undefined)要绑定的 this(可传 null/undefined)
返回值函数执行后的返回值函数执行后的返回值绑定了 this 的新函数
后续参数是否可追加不可(一次性传完)不可(一次性传完)可以(bind 后还能继续传参)
常用场景借用方法、链式调用处理类数组、Math.max.apply()事件处理、柯里化、固定 this

代码对比(最直观的区别)

function say(greeting, punctuation) {
  console.log(`${greeting}, 我是 ${this.name}${punctuation}`);
}

const person = { name: "小明" };


// 1. call —— 立即执行,参数逐个传入
say.call(person, "你好", "!");      
// 你好, 我是 小明!


// 2. apply —— 立即执行,参数用数组
say.apply(person, ["早上好", "~~"]); 
// 早上好, 我是 小明~~


// 3. bind —— 不执行,返回新函数
const sayHiToPerson = say.bind(person, "嘿");  
// 可以先绑定部分参数(柯里化)

sayHiToPerson("!");    
// 嘿, 我是 小明!

sayHiToPerson("呀~");   
// 嘿, 我是 小明呀~

经典使用场景对比

场景推荐使用为什么选它
借用数组方法(push、slice等)call / apply需要立即执行
求数组最大/最小值applyMath.max.apply(null, arr)(老写法)
Math.max(…arr) 的旧浏览器兼容写法apply数组展开运算符出现之前最常用
setTimeout / setInterval 固定 thisbind回调函数需要延迟执行
React / Vue 事件绑定bind常用于 constructor 中提前绑定 this
函数柯里化(partial application)bind可以分步传参
快速借用 console.log.applyapplyconsole.log.apply(console, arguments)

口诀总结(面试背这个很快)

  • call:打电话(Call)→ 参数像打电话一样一个个说马上打
  • apply:申请(Apply)→ 参数要打包成数组交上去,马上批
  • bind:绑定(Bind)→ 只绑住 this 和部分参数,不马上用,留着以后再调用

希望这个对比够清晰!如果想看手写 call/apply/bind 的实现代码也可以告诉我~

文章已创建 4725

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部