2011-05-31 81 views
1

我知道有一個聰明的方法來利用閉包並執行我正在尋找的操作,但我不確定它是什麼。在事件處理程序中關閉一個變量

在以下代碼:

var MyApp = { 
    innerObject : { 
    myData : "test value", 
    myMethod : function() { 
     // 'this' ends up referring to HTMLElement, not what I want 
     alert(this.myData); 
    } 
    } 
    open : function() { 
    document.getElementById('connectLink').addEventListener('click', this.innerObject.myMethod, false); 
    } 
} 
MyApp.open(); 

我期待的事件處理程序附加到使用id =「connectLink」的元素內部innerObject的方法。該方法訪問innerObject內的其他數據以執行其功能。我知道這與JavaScript中關鍵字this的棘手本質有關。有沒有一種模式可以解決這個問題?

回答

1

保持對它的引用this並通過一個匿名函數:

var self = this; 
document.getElementById('connectLink').addEventListener('click', function() { 
    self.innerObject.myMethod(); 
}, false); 

還記得你在IE中使用attachEvent

更新:

較新的瀏覽器提供.bind()它可以讓你的功能的情況下綁定到特定的對象。這可能是最乾淨的解決方案。上面的鏈接爲不支持它的瀏覽器提供了一個實現。

el.addEventListener(
    'click', 
    this.innerObject.myMethod.bind(this.innerObject), 
    false 
); 
+0

只是爲了澄清這是 alex 2011-05-31 00:49:30

2

請注意,按照慣例,以大寫字母開頭的標識符代表構造函數。

Remeber該this由呼叫設定,而不是由該聲明或初始化(除ES 5 綁定,這是不準備好一般Web上使用尚未)。

你可以這樣做:

myMethod : function() { 
     alert(MyApp.innerObject.myData); 
} 

或者您可以使用module pattern的參考保持到innerObject創建MyApp的(有some who think it's overused)。但即便如此,監聽器中的this也會引用它所設置的元素。

+0

會採用模塊模式實際上有助於解決處理程序中引用myData的問題嗎?如果是這樣,我真的很想這樣做。費利克斯的答案聽起來像是可行的,但它使我的代碼更不可讀。你將如何使用模塊模式構造這個功能? – Ankur 2011-05-31 01:02:06

+0

指定爲**偵聽器**的函數可以對* MyApp.innerObject *具有閉包,並將其作爲 .property引用。菲利克斯的回答暗示了封閉,但並沒有真正幫助實施。在任何情況下,我都會使用完全限定的引用 - 顯然它引用它更簡單,更易於維護。 – RobG 2011-05-31 02:22:08

相關問題