1. 程式人生 > >事件處理函式中的this

事件處理函式中的this

[color=red]這個問題我遇到過,但是我不是很明白下面的講述-----ajax in action4.3.1[/color]

我們已經得到了一個DOM元素的控制代碼,分配了一個回撥函式給onclick屬性。當DOM元素收到滑鼠點選事件時,回撥即被呼叫。然而,函式上下文(即變數this所確定的值——參見附錄B,可獲得關於JavaScript Function物件的完整討論)賦值為收到事件的DOM節點。根據函式最初是在什麼地方宣告以及如何宣告的,情況會有所不同,這可能會把人搞糊塗。

讓我們通過一個例子來研究這個問題。我們定義了一個表示按鈕物件的類,它有一個到DOM節點的引用、一個回撥處理函式,以及當點選按鈕時顯示出的一個值。當滑鼠點選事件發生時,按鈕的任何例項都將以同樣的方式響應,因此我們定義回撥處理函式作為按鈕類的一個方法。這些說明對於初學者已經足夠了,下面讓我們看看程式碼。這裡是按鈕類的建構函式。

function Button(value,domEl){

this.domEl=domEl;

this.value=value;

this.domEl.onclick=this.clickHandler;

}

繼續定義一個事件處理函式作為Button類的一部分。

Button.prototype.clickHandler=function(){

alert(this.value);

}

這段程式碼看起來很直觀,但是它並沒有做我們希望它做的事情。警告框通常會返回訊息unde- fined,而不是傳遞到建構函式的value屬性。為什麼呢?當點選DOM元素時,函式click- Handler由瀏覽器呼叫,它設定函式上下文到DOM元素,而不是Button的JavaScript物件。於是,this.value指向DOM元素的value屬性,而不是Button物件的value屬性。你永遠也不可能通過檢視事件處理函式的宣告來發現這個情況,是不是?

我們可以通過向DOM元素傳遞Button物件的引用來解決這個問題,也就是,按下面的方法修改建構函式:

function Button(value,domEl){

this.domEl=domEl;

this.value=value;

this.domEl.buttonObj=this;

this.domEl.onclick=this.clickHandler;

}

DOM元素仍然沒有value屬性,但是它有一個到Button物件的引用,可以從那裡得到value。通過對事件處理函式做如下修改,我們的工作就完成了:

Button.prototype.clickHandler=function(){

var buttonObj=this.buttonObj;

var value=(buttonObj && buttonObj.value) ?

buttonObj.value : "unknown value";

alert(value);

}

DOM節點引用Button物件,Button物件引用它的value屬性,這樣事件處理函式就做了我們希望它做的事情。我們可以直接給DOM節點附加value,不過附加一個指向整個後端物件的引用可以使這種模式容易地用於任意複雜的物件,順便說一句,我們在這裡已經實現了一個小的MVC模式,其中DOM元素作為後端物件模型的前端檢視。