js手写(二):实现call,apply,bind方法

109 阅读1分钟

1.简析

1.区别

call,apply,bind方法用于改变函数this指向,其区别在于call传参是逐一传入,apply传参是仅接受数组或伪数组,bind传参也是逐一传入,但是通过bind绑定的函数不会立即调用。

2.思路

  • 对于call和apply函数,其主要目的有两个,一个是函数需要调用,一个是this指向需要改变;
  • 对于bind函数,其主要目的也有两个,一个是函数不会调用,需要后续手动调用,一个是this指向需要改变。据此去思考如何书写

2.手写call函数

Function.prototype.myCall = function(target = window, ...args) {
  // this为需要改变this指向的函数,给目标对象添加这个函数并调用
  target.fn = this
  const res = target.fn(...args)
  delete target.fn
  return res
}

3.手写apply函数

Function.prototype.myApply = function(target = window, arg) {
  // 参数必须为数组或者伪数组
  if (!args || !args[Symbol.iterator]) {
    throw new Error('arguments is needed ArrayLike')
  }
  target.fn = this
  const res = target.fn(arg)
  delete target.fn
  return res
}

4.手写bind函数

Function.prototype.myBind = function(target = window, ...args) {
  // 为保证this指向正确,需事先保存this
  const currentThis = this
  // 注意参数,返回的函数和调用myBind函数时都可以传参,需要将参数合并
  return function(...args2) {
    target.fn = currentThis
    const res = target.fn(...args.concat(args2))
    delete target.fn
    return res
  }
}