手写call bind apply | 刷题打卡

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、call

call 接收多个参数,第一个参数为函数执行指定的上下文,剩余参数为函数执行实际入参。

1.代码实现

Function.prototype.mycall = function (ctx) {
  if (typeof this !== "function") return

  let args = [...arguments].slice(1)
  let result
  ctx = ctx || window

  ctx.fn = this

  result = ctx.fn(...args)
  delete ctx.fn
  return result
}
复制代码

2.实现逻辑

  1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可 能出现使用 call 等方式调用的情况。
  2. 判断传入上下文对象是否存在,如果不存在,则设置为 window 。
  3. 处理传入的参数,截取第一个参数后的所有参数。
  4. 将函数作为上下文对象的一个属性。
  5. 使用上下文对象来调用这个方法,并保存返回结果。
  6. 删除刚才新增的属性。
  7. 返回结果。

二、apply

apply 接收两个参数,,第一个参数为函数执行指定的上下文,第二个参数是一个数组,数组中的每一项都会作为函数执行的实际参数。

1.代码实现

Function.prototype.myapply = function (ctx) {
  if (typeof this !== "function") return
  
  let args = arguments[1]
  let result
  ctx = ctx || window

  ctx.fn = this

  result = ctx.fn(args || null)
  delete ctx.fn
  return result
}
复制代码

2.实现逻辑

  1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可 能出现使用 call 等方式调用的情况。
  2. 判断传入上下文对象是否存在,如果不存在,则设置为 window 。
  3. 将函数作为上下文对象的一个属性。
  4. 判断参数值是否传入
  5. 使用上下文对象来调用这个方法,并保存返回结果。
  6. 删除刚才新增的属性
  7. 返回结果

三、bind

bind 接收多个参数,第一个参数为函数执行指定的上下文,剩余参数为函数执行时的实际入参,与以上两个方法的区别是bind不会直接执行函数,而是将函数存为绑定好作用域的新函数存下来,供调用时使用。

1.代码实现

Function.prototype.mybind = function (ctx) {
  if (typeof this !== "function") return

  let args = [...arguments].slice(1)
  let fn = this

  return function Fn() {
    return fn.apply(
      this instanceof Fn ? this : context,
      args.concat(...arguments)
    )
  }
}
复制代码

2.实现逻辑

  1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可 能出现使用 call 等方式调用的情况。
  2. 保存当前函数的引用,获取其余传入参数值。
  3. 创建一个函数返回
  4. 函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的 情况,这个时候需要传入当前函数的 this 给 apply 调用,其余情况都传 入指定的上下文对象。

END

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享