2021/01/30 - 模拟实现bind函数
lxinr opened this issue · 1 comments
lxinr commented
bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数
function.bind(thisArg[, arg1[, arg2[, ...]]])thisArg: 用绑定函数时作为this参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用bind在setTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果bind函数的参数列表为空,或者thisArg是null或undefined,执行作用域的this将被视为新函数的thisArgarg1, arg2, ...: 当目标函数被调用时,被预置入绑定函数的参数列表中的参数
实现:
Function.prototype.myBind = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var self = this
var args = Array.prototype.slice.call(arguments, 1) // 从第二个参数起作为入参
// 通过一个空函数来进行中转
var fNOP = function() {}
var fBound = function() {
var arrs = Array.prototype.slice.call(arguments) // 如果还有传参,则也加入入参
// 当作为构造函数时,this 指向实例,此时结果为 true,将绑定函数的 this 指向该实例,可以让实例获得来自绑定函数的值
// 当作为普通函数时,this 指向 window,此时结果为 false,将绑定函数的 this 指向 context
return self.apply(this instanceof fNOP ? this : context, args.concat(arrs))
}
// 下述代码其实就类似于fBound.prototype = Object.create(this.prototype)
// 为了让 fBound 构造的实例能够继承绑定函数的原型中的值,这是原生bind所具有的能力
fNOP.prototype = this.prototype
fBound.prototype = new fNOP()
return fBound
}Ha0ran2001 commented
@lxinr 。当使用 bind 在 setTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object.这句话怎么理解?