2011-09-02 165 views
2
Function.prototype.bind = function() { 
    var _this = this, 
     original = _this, 
     args = Array.prototype.slice.call(arguments), 
     _obj = args.shift(), 
     func = function() { 
      var _that = _obj; 
      return original.apply(_that, args.concat(
      Array.prototype.slice.call(
      arguments, args.length))); 
     }; 
    func.bind = function() { 
     var args = Array.prototype.slice.call(arguments); 
     return Function.prototype.bind.apply(_this, args); 
    } 
    return func; 
}; 

我知道這是一個綁定函數。但我不明白它在做什麼,特別是args.concat部分。 concat做什麼?另外,.bind方法做什麼.apply.call不能?這段代碼做了什麼?

+0

'bind'返回一個函數,'call'和'apply'調用一個函數,它們是不同的動物。當你想要確保稍後使用的函數被特定的上下文調用時使用'bind',同時也可以選擇將參數綁定到函數。 –

回答

3

bind函數採用函數並確保它是總是綁定到特定的this值。最簡單的例子是事件處理程序。默認情況下,事件處理程序的this值綁定到window。但是,讓我們說,你想用一個對象的方法作爲聽衆,並在監聽改變一些屬性:

var thing = { 
    answer : 4, 
    listener : function() { 
     this.answer = 42; 
    } 
} 
window.onload = thing.listener; 

在onload事件,而不是thing.answer正在改變像預期,window.answer現在是42.所以,我們使用bind

window.onload = thing.listener.bind(thing); 

所以,bind返回一個函數,調用時,調用原始的功能,但與指定this值。

[].concat簡單地增加的參數的陣列 - 所以[].concat(5, 4)返回[5, 4],並[5, 4].concat([42])返回[5, 4, 42]。在這種情況下,它用於連接參數 - 您可以將參數傳遞給bind函數,該函數在函數被調用時將作爲參數傳遞。連接起作用,所以當你調用綁定函數時,你傳遞的參數也被傳遞。

2

它似乎是shimFunction.bind()

但我不明白它在做什麼,特別是args.concat部分。 concat是做什麼的?

Array.concat()連接兩個或更多個Array S(以及其它值到Array)。

而且,什麼.bind方法做到這一點.apply.call不能?

它返回一個函數的引用,this綁定到任何你想要的。

var newFn = fn.bind(['a', 'b', 'c']); 

// This will call `fn()` with the above `Array` as `this`. 
newFn('first arg', 'second arg'); 

它適用於例如咖喱,返回一個已經設置參數的函數(因爲在bind()中設置了this以外,可以設置默認參數)。

+0

奇怪的(或不同的)部分是它爲被返回的函數添加一個'.bind'屬性'func.bind = function(){...'這樣如果你調用'.bind()''反對一個'.bind()'的* result *函數,原型''。bind()'被遮蔽,並且它總是隻綁定到原始函數。這是與標準'.bind()'的偏差。 – user113716

+0

...它也非常奇怪地重複其變量2,引用同一個項目的不同名稱。它放棄傳遞給與原始綁定參數位於相同索引的綁定函數調用的參數。非常奇怪的功能。 – user113716

+0

@patrick我確實注意到了重複。奇怪。 – alex