call、apply、bind 的区别?如何手写实现?

三者对比

方法 参数 执行时机 返回值
call (thisArg, arg1, arg2, ...) 立即执行 函数返回值
apply (thisArg, [argsArray]) 立即执行 函数返回值
bind (thisArg, arg1, ...) 返回新函数 新函数

手写 call

Function.prototype.myCall = function (ctx, ...args) {
  ctx = ctx == null ? globalThis : Object(ctx)
  const key = Symbol('fn')
  ctx[key] = this
  const result = ctx[key](...args)
  delete ctx[key]
  return result
}

手写 apply

Function.prototype.myApply = function (ctx, args = []) {
  ctx = ctx == null ? globalThis : Object(ctx)
  const key = Symbol('fn')
  ctx[key] = this
  const result = ctx[key](...args)
  delete ctx[key]
  return result
}

手写 bind

Function.prototype.myBind = function (ctx, ...outerArgs) {
  const fn = this
  return function (...innerArgs) {
    // 支持 new 调用
    if (new.target) {
      return new fn(...outerArgs, ...innerArgs)
    }
    return fn.apply(ctx, [...outerArgs, ...innerArgs])
  }
}

核心原理

利用 对象.方法() 的隐式绑定规则,将函数作为对象的属性临时调用,使 this 指向该对象。用 Symbol 避免属性名冲突。

同分类其他题目