一、bind方法
让我们看一下MDN上对bind方法的解释:bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
也就是说bind()方法会:
那bind创建的这个新函数还有其他什么特性吗?
调用绑定函数时作为 this 参数传递给目标函数的值。 如果使用 new 运算符构造绑定函数,则忽略该值。
举个下面的例子:由bind创建的新函数bindFoo作为构造函数时,其创建的实例newBindFoo并不指向bindFoo绑定的obj,而是指向bindFoo。
var obj={
name:"Melody"
}
var name="huyang"
function foo(tel){
console.log(this.name)
console.log(tel)
}
var bindFoo=foo.bind(obj,"110")
bindFoo()
//Melody
//110
var newbindFoo=new bindFoo();
//undefinde
//110
先实现前两个特性,用call模拟bind绑定this,并且对arguments进行分割处理实现其余参数传递
Function.prototype.bind2 = function (context) {
var self = this;
var args=Array.prototype.slice.call(arguments,1)//模拟bind时的传参
return function () {
var bindArgs=Array.prototype.slice(arguments)//模拟执行bind的返回函数时的传参
self.apply(context,args.concat(bindArgs));//修改返回函数的this指向为context,并将bind时和执行bind的返回函数传入的参数concat后绑定给返回函数。
}
}
修改返回函数的作用域链,使其指向绑定函数,这样返回函数生成的实例就可以继承绑定函数的原型啦。
Function.prototype.bind2 = function (context) {
var self = this;
var args=Array.prototype.slice.call(arguments,1)//模拟bind时的传参
var foo=function() {
var bindArgs=Array.prototype.slice(arguments)//模拟执行bind的返回函数时的传参
self.apply(this instanceof self ? this : context, args.concat(bindArgs));
// 由于下方修改返回函数的prototype为绑定函数的prototype,当返回函数作为构造函数使用时,实例this instanceof self必定为真(instanceof判断的底层原理实际上就是根据原型链判断的)
// 当作为普通函数时,this 指向 window,self 指向绑定函数,此时结果为 false,当结果为 false 的时候,this 指向绑定的 context
}
foo.prototype=this.prototype
return foo
}
需要注意的点:
arguments只是具有length属性且可以通过index读取的类数组对象,并没有slice等数组方法,要想对arguments使用数组方法必须得将arguments转换为真正的数组。故,使用Array.prototype.slice.call(arguments),对Array原型链中的slice方法调用call(或apply),传入arguments作为其上下文,然后返回arguments转换后的数组。
这些API的特点以及具体用法我就不介绍了,相信你如果奔着手动实现的方向来看,那么你一定对它很了解,核心: this永远指向最后调用它的对象
sayColor() 调用 bind() 并传入对象 o ,创建了 o bjectSayColor() 函数。 object-SayColor() 函数的 this 值等于 o ,因此即使是在全局作用域中调用这个函数,bind与apply、call最大的区别就是:bind不会立即调用
你看,我一直在使用JavaScript中的bind()试验。事实证明,我们可以在多个场合,包括处理我几周前提到的闭包问题中,使用bind。
bind 和 apply,call 是 JS 修改 this 指向的三把利器 。对于 apply,call 来说,bind 的区别在于会返回一个修改了 this 指向的新函数,并不会立即执行。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!