bind方法解釋

MDN的解釋是:bind()方法會創建一個新函數,稱爲綁定函數,當調用這個綁定函數時,綁定函數會以創建它時傳入 bind()方法的第一個參數作爲 this,傳入 bind() 方法的第二個以及以後的參數加上綁定函數運行時本身的參數按照順序作爲原函數的參數來調用原函數。

直接來看看具體如何使用,在常見的單體模式中,通常我們會使用 _this , that , self 等保存 this ,這樣我們可以在改變了上下文之後繼續引用到它。 像這樣:

var foo = {
    bar : 1,
    eventBind: function(){
        var _this = this;
        $('.someClass').on('click',function(event) {
            /* Act on the event */
            console.log(_this.bar);     //1
        });
    }
}

由於 Javascript 特有的機制,上下文環境在 eventBind:function(){ } 過渡到 $('.someClass').on('click',function(event) { }) 發生了改變,上述使用變量保存 this 這些方式都是有用的,也沒有什麼問題。當然使用 bind() 可以更加優雅的解決這個問題:

var foo = {
    bar : 1,
    eventBind: function(){
        $('.someClass').on('click',function(event) {
            /* Act on the event */
            console.log(this.bar);      //1
        }.bind(this));
    }
}

在上述代碼裏,bind() 創建了一個函數,當這個click事件綁定在被調用的時候,它的 this 關鍵詞會被設置成被傳入的值(這裏指調用bind()時傳入的參數)。因此,這裏我們傳入想要的上下文 this(其實就是 foo ),到 bind() 函數中。然後,當回調函數被執行的時候, this 便指向 foo 對象。再來一個簡單的栗子:

var bar = function(){
console.log(this.x);
}
var foo = {
x:3
}
bar(); // undefined
var func = bar.bind(foo);
func(); // 3

這裏我們創建了一個新的函數 func,當使用 bind() 創建一個綁定函數之後,它被執行的時候,它的 this 會被設置成 foo , 而不是像我們調用 bar() 時的全局作用域。


有個有趣的問題,如果連續 bind() 兩次,亦或者是連續 bind() 三次那麼輸出的值是什麼呢?像這樣:

var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
var sed = {
    x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?
 
var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?

答案是,兩次都仍將輸出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是無效的。更深層次的原因, bind() 的實現,相當於使用函數在內部包了一個 call / apply ,第二次 bind() 相當於再包住第一次 bind() ,故第二次以後的 bind 是無法生效的。

  apply、call、bind比較

那麼 apply、call、bind 三者相比較,之間又有什麼異同呢?何時使用 apply、call,何時使用 bind 呢。簡單的一個栗子:


var obj = {
    x: 81,
};
 
var foo = {
    getX: function() {
        return this.x;
    }
}
 
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

三個輸出的都是81,但是注意看使用 bind() 方法的,他後面多了對括號。

也就是說,區別是,當你希望改變上下文環境之後並非立即執行,而是回調執行的時候,使用 bind() 方法。而 apply/call 則會立即執行函數。

 

再總結一下:

  • apply 、 call 、bind 三者都是用來改變函數的this對象的指向的;
  • apply 、 call 、bind 三者第一個參數都是this要指向的對象,也就是想指定的上下文;
  • apply 、 call 、bind 三者都可以利用後續參數傳參;
  • bind 是返回對應函數,便於稍後調用;apply 、call 則是立即調用 。
本文轉自:http://www.cnblogs.com/coco1s/p/4833199.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章