bind函数的实现有几个重点如下
(1)bind 返回一个函数
(2)返回的函数需要使用 apply 绑定 this
(3)需要把 bind 时候的参数和后续调用的时候的参数组合起来
Function.prototype.myBind = function(context) {
if (typeof this !== 'function') {
return
}
const args = [...arguments].slice(1)
const fn = this
return function Fn() {
// 这句代码的解析请看文章正文
const target = this instanceof Fn ? this : context
return fn.apply(target, args.concat([...arguments]))
}
}
function setName(name) {
this.name = name
}
const obj = {
age: 1
}
// 使用原生的 bind 的结果
const setName1 = setName.bind(obj)
setName1('origin')
console.log('正确结果', obj)
// 使用我们自己写的 bind 的结果
const setName2 = setName.myBind(obj)
setName1('custom')
console.log('自定义的结果', obj)
const name11 = new setName1('new origin bind')
console.log('origin', name11)
const name22 = new setName2('new my bind')
console.log('custom', name22)
代码解释
const target = this instanceof Fn ? this : context
这行代码,是因为 bind 返回一个函数,而任何一个函数都有可能使用 new 操作符作为构造函数,你要知道对于this 指针 new 操作符的优先级比硬绑定(bind)的优先级高。可以不写这行代码测试一下。
在测试一下正确的结果
经常把 bind 、call、apply搞混,可以先记住 call 和apply 是调用函数,bind 是返回函数。