三者都用来改变函数执行时的 this,区别在于调用方式:call 从第二个参数起逐个传参,apply 把参数打包成数组传入,两者都会立即执行函数;bind 则返回一个绑定了 this 与预设参数的新函数,本身不执行,留到下次调用。记住这句口诀即可:call 逐个传、apply 数组传、bind 返回函数。
实战场景非常多:用 call 借用别人的方法(比如用 Array.prototype.map 处理类数组 arguments),用 apply 把数组展开成 Math.max 的参数,用 bind 把回调函数的 this 钉在组件实例上以防丢失。它们只改 this 不改函数本身,严格模式下 this 还可能是 undefined,需注意判空。
const obj = { name: '前端' }; function greet(greeting, punct) { console.log(greeting + ', ' + this.name + punct); } greet.call(obj, '你好', '!'); // 你好, 前端! greet.apply(obj, ['Hello', '.']); // Hello, 前端. const bound = greet.bind(obj, '嗨'); bound('?'); // 嗨, 前端? // 借用数组方法处理类数组 function sumAll() { return Array.prototype.reduce.call( arguments, (acc, cur) => acc + cur, 0); } console.log(sumAll(1, 2, 3)); // 6 // bind 的 this 不可再改 const fixed = bound.call({ name: '后端' }, '!'); fixed('。'); // 嗨, 前端。