标准答案
- 核心区别:call、apply、bind 都可以改变普通函数执行时的 this。call 会立即调用函数,参数逐个传入;apply 也会立即调用函数,但参数以数组或类数组形式传入;bind 不会立即执行,而是返回一个绑定了 this 和部分参数的新函数。
- 使用场景:已知参数个数并且要立刻执行时用 call;参数天然是数组或类数组时用 apply;需要把函数传给别处稍后执行,同时固定 this 或预置部分参数时用 bind。
- bind 实现:手写 bind 的核心是返回一个包装函数,在包装函数内部用原函数的 apply 或 Reflect.apply 执行,并把预置参数和调用时参数拼接起来。
- new 边界:完整 bind 还要处理构造调用。如果绑定函数被当作构造函数调用,this 应该指向新实例,而不是最初 bind 传入的对象。
题目解析
这里通常会从用法延伸到手写实现。基础层面要说清“是否立即执行”和“参数形式”;进一步要知道 bind 遇到 new 时的行为。
call/apply/bind 对箭头函数的 this 不生效,因为箭头函数没有自己的 this。它们仍然可以传参调用箭头函数,但不能改变箭头函数捕获的 this。
代码示例
下面是 bind 的核心版实现,重点表达 this 绑定和参数预置。
JavaScript
Function.prototype.myBind = function (context, ...presetArgs) {
const fn = this
return function bound(...laterArgs) {
return fn.apply(context, [...presetArgs, ...laterArgs])
}
}
function greet(prefix, suffix) {
return prefix + this.name + suffix
}
const sayHi = greet.myBind({ name: 'Alice' }, 'Hi, ')
sayHi('!') // Hi, Alice!常见误区
- 误以为 bind 会立刻执行函数。
- 手写 bind 时忽略参数预置和调用时参数拼接。
- 认为 call/apply/bind 能改变箭头函数 this。