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;
};