[JavaScript] 纯文本查看 复制代码
Function.prototype.bind2 = function(context = window){
// 判断调用bind2的东西是否是函数
if (typeof this !== 'function'){
throw new TypeError('error')
}
// step1: 获取到调用bind2的绑定函数
let _this = this
// step2: 保存bind2传进来的参数,第一个参数为改变this的context,从第二个参数开始
let bindArgs = [...arguments].slice(1)
// step3:声明一个空函数作为一个中转的构造函数,用于保持fBond.prototype的纯洁
let fNOP = function(){}
// step4: 返回一个新的函数
let fBond = function(){
// args 是返回的新函数传进来的参数
let args = [...arguments].slice()
// 这里有两种情况,
// ①如果绑定函数是一个构造函数,那么this就是实例对象,_this就是构造函数,此时函数内的this改变指向的功能作废
// ②如果绑定函数不是构造函数,那么this就是指向window,因为返回的新函数是运行在全局环境中,_this就是绑定函数本身
_this.apply(this instanceof _this? this : context, args.concat(bindArgs ))
}
// step5:修改fNOP.prototype的指向,原本fNOP.prototype是Function.prototype,现在改成绑定函数的原型对象,继承绑定函数的方法和属性
fNOP.prototype = this.prototype
// step6: fBond.prototype指向fNOP构造函数的实例,这样既可以继承this.prototype,又不会主动修改或添加this.prototype中的值,即使修改或添加也是放在了实例对象上
fBond.prototype = new fNOP()
// step7:返回fBond
return fBond
}