手写bind实际上就是考验对柯里化和new的理解,所以首先要搞明白bind会不会对构造函数有影响

function person(name) {
  this.name = name
  console.log(this.age);
}

const son = {
  age: '18'
}

const abc = person.myBind(son, 'hello')

abc()  // 18

const b = new abc('wumao') // log打印undefined

console.log(b);//{ name: 'hello' } //说明bind在this不起作用,但是参数上还是起作用的

从以上结果来看bind不影响new过程中this的指向(new一个函数的时候,如果返回的是复杂数据类型,则返回这个复杂数据类型,如果是简单数据类型,则返回这个简单数据类型的包装对象,并且它的原型会继承该构造函数的原型)

这时候我们开始写代码

Function.prototype.myBind = function (obj, ...args) {
  //首先存储一下要绑定的函数
  const fn = this
  //因为肯定不止一个参数,所以这里需要柯里化返回另外一个函数
  const returnFn = function (...secondArgs) {
    // 这里面判断是否使用了new(this指向实例化对象,通过instanceof返回的构造函数是否为true)
    const isNew = this instanceof returnFn
    // 如果使用的是构造函数,则是实例对象,否则是这个被绑定的对象
    const thisObj = isNew ? this : Object(obj)
    // 用call绑定this,并且传递参数
    return fn.call(thisObj, ...args, ...secondArgs)
  }
  //复制调用函数的prototype给返回的函数
  returnFn.prototype = Object.create(fn.prototype);


  return returnFn
}
Last modification:March 10, 2021
If you think my article is useful to you, please feel free to appreciate