讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議73:函數綁定有價值 >

建議73:函數綁定有價值

函數綁定就是為了糾正函數的執行上下文,特別是當函數中帶有this關鍵字的時候,這一點尤其重要,稍微不小心,就會使函數的執行上下文發生跟預期不同的改變,導致代碼執行上的錯誤。函數綁定具有3個特徵:

❑函數綁定要創建一個函數,可以在特定環境中以指定參數調用另一個函數。

❑一個簡單的bind函數接收一個函數和一個環境,返回一個在給定環境中調用給定函數的函數,並且將所有參數原封不動地傳遞過去。

❑被綁定函數與普通函數相比有更多的開銷,它們需要更多內存,同時也因為多重函數調用而稍微慢一點,最好只在必要時使用。

第一個特徵常常和回調函數及事件處理函數一起使用。


var handler={

message:'Event handled',

handleClick:function(event){

alert(this.message);

}

};

var btn=document.getElementById('my-btn');

EventUtil.addHandler(btn,'click',handler.handleClick);//undefined


出現上述結果的原因在於沒有保存handler.handleClick環境(上下文環境),所以this對像最後指向了DOM按鈕而非handler。可以使用閉包修正此問題:


var handler={

message:'Event handled',

handleClick:function(event){

alert(this.message);

}

};

var btn=document.getElementById('my-btn');

EventUtil.addHandler(btn,"click",function(event){

handler.handleClick(event);

});


這是特定於這段代碼的解決方案。創建多個閉包可能會令代碼變得難於理解和調試,因此,很多JavaScript庫實現了一個可以將函數綁定到指定環境的函數bind。

bind函數的功能是提供一個可選的執行上下文傳遞給函數,並且在bind函數內部返回一個函數,以糾正在函數調用上出現的執行上下文發生的變化。最容易出現的錯誤就是回調函數和事件處理程序一起使用。


function bind(fn,context){

return function{

return fn.apply(context,arguments);

};

}


在bind中創建一個閉包,該閉包使用apply調用傳入的參數,並為apply傳遞context對像和參數。

注意:這裡使用的arguments對象是內部函數的,而非bind的。在調用返回的函數時,會在給定的環境中執行被傳入的函數並給出所有參數。


var handler={

message:'Event handled',

handleClick:function(event){

alert(this.message);

}

};

var btn=document.getElementById('my-btn');

EventUtil.addHandler(btn,"click",bind(handler.handlerClick,handler));