call和apply的使用和区别再也不作阐述,能够参考个人另外一篇随笔《JavaScript中call和apply方法的使用》(https://www.cnblogs.com/lcr-smg/p/10067398.html),这里只是针对bind的用法及与call和apply二者的区别。html
bind的用法app
bind() 方法与 apply 和 call 很类似,也是能够改变函数体内 this 的指向。函数
MDN的解释是:bind()方法会建立一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以建立它时传入 bind()方法的第一个参数做为 this,传入 bind() 方法的第二个以及之后的参数加上绑定函数运行时自己的参数按照顺序做为原函数的参数来调用原函数。直接来看看具体如何使用,在常见的单体模式中,一般咱们会使用 _this , that , self 等保存 this ,这样咱们能够在改变了上下文以后继续引用到它。 像这样:this
1 var foo = { 2 bar : 1, 3 eventBind: function(){ 4 var _this = this; 5 $('.someClass').on('click',function(event) { 6 /* Act on the event */ 7 console.log(_this.bar); //1 8 }); 9 } 10 }
因为 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $('.someClass').on('click',function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。固然使用 bind() 能够更加优雅的解决这个问题:spa
1 var foo = { 2 bar : 1, 3 eventBind: function(){ 4 $('.someClass').on('click',function(event) { 5 /* Act on the event */ 6 console.log(this.bar); //1 7 }.bind(this)); 8 } 9 }
在上述代码里,bind() 建立了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。所以,这里咱们传入想要的上下文 this(其实就是 foo ),到 bind() 函数中。而后,当回调函数被执行的时候, this 便指向 foo 对象。再来一个简单的栗子:code
1 var bar = function(){ 2 console.log(this.x); 3 } 4 var foo = { 5 x:3 6 } 7 bar(); // undefined 8 var func = bar.bind(foo); 9 func(); // 3
这里咱们建立了一个新的函数 func,当使用 bind() 建立一个绑定函数以后,它被执行的时候,它的 this 会被设置成 foo , 而不是像咱们调用 bar() 时的全局做用域。有个有趣的问题,若是连续 bind() 两次,亦或者是连续 bind() 三次那么输出的值是什么呢?像这样:htm
1 var bar = function(){ 2 console.log(this.x); 3 } 4 var foo = { 5 x:3 6 } 7 var sed = { 8 x:4 9 } 10 var func = bar.bind(foo).bind(sed); 11 func(); //? 12 13 var fiv = { 14 x:5 15 } 16 var func = bar.bind(foo).bind(sed).bind(fiv); 17 func(); //?
答案是,两次都仍将输出 3 ,而非期待中的 4 和 5 。缘由是,在Javascript中,屡次 bind() 是无效的。更深层次的缘由, bind() 的实现,至关于使用函数在内部包了一个 call / apply ,第二次 bind() 至关于再包住第一次 bind() ,故第二次之后的 bind 是没法生效的。对象
那么 apply、call、bind 三者相比较,之间又有什么异同呢?什么时候使用 apply、call,什么时候使用 bind 呢。简单的一个栗子:blog
1 var obj = { 2 x: 81, 3 }; 4 5 var foo = { 6 getX: function() { 7 return this.x; 8 } 9 } 10 11 console.log(foo.getX.bind(obj)()); //81 12 console.log(foo.getX.call(obj)); //81 13 console.log(foo.getX.apply(obj)); //81
三个输出的都是81,可是注意看使用 bind() 方法的,他后面多了对括号。事件
也就是说,区别是,当你但愿改变上下文环境以后并不是当即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会当即执行函数。
总结: