带你手动实现bind方法,让你收获满满

1.手动实现bind方法的要点

  • 当作为this参数传入的值为原始类型数据时,该数据会被包装成对象。传入null或者undefined时,this会被替换为window。
  • 传入一般对象时,返回的函数内部this指向该对象。
  • bind方法一个经典用法就是偏函数的应用。让函数可以拥有预设参数。
  • 最重要的一点就是绑定函数作为构造函数去调用。MDN:绑定函数自动适应于使用 new 操作符去构造一个由目标函数创建的新实例。当一个绑定函数是用来构建一个值的,原来提供的 this 就会被忽略。不过提供的参数列表仍然会插入到构造函数调用时的参数列表之前。

意思就是:当绑定函数作为构造函数去调用的时候,它被提供的this会被忽略掉。然后,就会像一般的构造函数一样去新建对象实例了。
示例:

const obj = {
    name: 'ha'
}

function Student(name){
    this.name = name;
}

const newS = Student.bind(obj, 23); // obj被忽略

const newObj = new newS(1);

console.log(obj);  // {name: "ha"}  obj的name属性值并未被改变
console.log(newObj);  // Student {name: 23}

如果不用new操作构造函数去生成对象实例的话,那么提供的this参数就会生效。

const obj = {
    name: 'ha'
}

function Student(name){
    this.name = name;
}

const newS = Student.bind(obj, 23); // obj的name属性会被改变

const newObj = newS(1); // 去掉了new操作符

console.log(obj);  // {name: 23}  obj的name属性值并未被改变
console.log(newObj);  // undefined

2.手动实现bind方法

// 手动实现bind方法
// MDN:关于绑定函数,做了如下说明:指的是某一函数(目标函数)调用了bind()方法后,原地生成的函数,为绑定函数。
Function.prototype.myBind = function (context, ...args) {
    const self = this;
    // 最重要的是返回一个函数
    context = [null, undefined].includes(context) ? window : {
      number: new Number(context),
      boolean: new Boolean(context),
      string: new String(context)
    }[typeof context];

    const fBound = function() {
      // 这里不要忘了加上return
      // 另外,就是如果new了绑定函数,那么传递给目标函数的this,即context参数就被忽略。否则,生效。
      return self.apply(this instanceof fBound ? this : context || window, args.concat(Array.prototype.slice.call(arguments)));

    }

    fBound.prototype = Object.create(self.prototype); // new出来的实例的原型,应为目标函数的原型

    return fBound;
  };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章