我目前正在爲我正在開發的項目構建一個非常簡單的Observer類。我已成功實施了訂閱,取消訂閱和通知方法。當使用「常規」功能(即:var f = function())時,一切都按預期工作。但是,當我將一個匿名函數傳遞給subscribe方法,然後嘗試取消訂閱傳遞「相同」匿名函數時,它(如預期的那樣)不會從我的數組中刪除函數(畢竟他們是不同的) 。Javascript中的匿名函數引用
這裏是我的訂閱和退訂方法
this._subscribers = {};
subscribe: function(type, callback) {
if (isUndefined(this._subscribers[type])) {
this._subscribers[type] = [];
}
this._subscribers[type].push(callback);
},
unsubscribe: function(type, callback) {
if (this._subscribers[type] instanceof Array) {
var index = this._subscribers[type].indexOf(callback);
if (index >= 0) {
this._subscribers[type].splice(index, 1);
}
}
},
這裏就是我與測試代碼:
var o = new gaf.events.Observable();
o.subscribe('testEvent', function(event) { alert('Got It!'); });
o.notify('testEvent');
// Correct alerts 'Got It!'
o.unsubscribe('testEvent', function(event) { alert('Got It!'); });
o.notify('testEvent')
// Incorrectly alerts 'Got It!'
我知道我可以使用一個對象(即:_subscribers [事件] = { }),然後當有東西訂閱我可以添加一個新的屬性等於回調和等於回調的值。這將導致JavaScript將回調轉換爲字符串。然後我可以使用該字符串查找它(假設sub/unsub中傳遞的方法完全相同)。
但是,這是一個移動項目,我非常關心存儲可能長達數百個字符的字符串的屬性,因爲我們可能會收到大量的訂閱者。
還有其他的方法嗎?是否有任何SMALL(小,甚至)哈希庫我可以用來散列函數的字符串值並將其用作屬性?在數組中存儲回調的字符串值(所以我可以比較它)是否更好(而不是實際的回調)並使用eval()?
非常感謝提前!
編輯
首先,感謝所有的答覆!
每所有關於「爲什麼連通匿名」功能的問題 -
實在沒有理由一個人不能使用命名功能。事實上,我同意每個人都認爲命名功能將會是更好的解決方案。我只是收集信息並尋找解決方案,以便我可以構建出儘可能處理大多數情況的實施方案。
這樣做的另一個原因是,如果此Observable類的用戶(同事)將匿名函數傳遞給它並取消訂閱,會發生什麼情況。該功能實際上不會被取消訂閱,因此不會被清理。我有一件事反對孤立的數據:)
也許我應該是另一個問題,是否有可能測試回調是匿名還是不可以?我會假設不,但不會傷害要問。
`eval`是邪惡的。 – SLaks 2011-01-06 13:46:02
作爲一個移動項目,我不認爲你想通過複製匿名函數(一個用於訂閱,一個用於取消訂閱)來浪費空間。此外,您需要哈希庫的開銷(空間和性能)。散列庫需要對函數進行「串化」,然後對其進行散列。 「stringify」操作需要有適當的空格。所有這些聽起來都很讓人頭疼。我建議遵循將函數保存到變量或使用命名函數的最佳做法。 – 2011-01-06 14:30:51