标准答案

  1. 核心区别:call、apply、bind 都可以改变普通函数执行时的 this。call 会立即调用函数,参数逐个传入;apply 也会立即调用函数,但参数以数组或类数组形式传入;bind 不会立即执行,而是返回一个绑定了 this 和部分参数的新函数。
  2. 使用场景:已知参数个数并且要立刻执行时用 call;参数天然是数组或类数组时用 apply;需要把函数传给别处稍后执行,同时固定 this 或预置部分参数时用 bind。
  3. bind 实现:手写 bind 的核心是返回一个包装函数,在包装函数内部用原函数的 apply 或 Reflect.apply 执行,并把预置参数和调用时参数拼接起来。
  4. 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。

作者信息