2012-05-14 47 views
2

如何檢測對象的屬性是否在Javascript中發生了變化?當對象的屬性數量發生變化時(無論它是否獲得或丟失了屬性),我特別希望調用一個函數。我想避免使用方法,並設置和更改對象的屬性,因爲它會相當快速地變得笨拙,而setInterval顯然不是一種選擇。那麼,這可能嗎?有沒有辦法檢測對象的屬性何時被更改?


編輯:我專門尋找一種方式,通過類似於Array對象上什麼是length屬性來獲取一個對象的屬性的長度。我認爲無論何時添加或刪除索引,他們都會改變長度,但顯然情況並非如此。 Javascript的原始設計者如何管理這件事?

+1

它將可以在ES6中,我認爲... –

+0

你可以做100ms的間隔。這不會損害性能...... –

+0

所以現在絕對不可能?這太糟糕了......當ES6會滾動時,有什麼想法?另外,我可能有很多這樣的對象,就像我說的,'setInterval'不是一個選項。 –

回答

1

因此,總結一下我通過評論所說的一切:ES6將提供應該爲「新屬性」或「屬性刪除」等事件啓用處理程序的代理。 (儘管如此,我還沒有對此進行太多的研究。)不幸的是,代理需要幾年才能成爲跨瀏覽器。

至於對象的length屬性,你可以爲它定義一個getter函數,但是這會在IE8中破壞,因爲IE只在IE9中實現了getter。所以,這給你一個length()方法。所以:

function objectLength() { 
    return Object.keys(this).length; 
} 

,然後,你要確保你的對象有此功能(無論是作爲自己的財產,或繼承的屬性):

yourObj.length = objectLength; 

YourConstructor.prototype.length = objectLength; 
+0

+1,並接受全面和詳細的答案。 –

+0

@ElliotBonneville我忘了提及,'Object.keys'不是跨瀏覽器(它沒有在IE8/7,FF 3.6/5中實現),但是您可以手動爲這些瀏覽器實現它。要麼包含來自[MDN]的代碼(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys),要麼包含[ES5-shim](https://github.com/kriskowal)/es5-shim)到你的頁面。 –

+0

啊,沒錯,好吧。感謝提示,我會牢記這一點。 –

2

那麼,常見的做法是有一個getter和setter類型的函數來完成它,類似於骨幹模型的形式。您可以通過函數修改數據,然後在執行您想要執行的操作之前,該函數會執行額外的處理(如執行偵聽器,檢查屬性等)。

function ListenableObject(data){ 

    var that = this; 
    this.data = data; 
    this.listeners = []; 

    this.edit = function(newvalues){ 
     //modify data 
     //execute listeners 
    } 

    this.addListener = function(callback){ 
     that.listeners.push(callback); 
    } 
} 

var mydata = new ListenableObject({'foo':'bar'}); 

mydata.addListener(function(){...callback...}); 

mydata.edit(somedata); 
+0

就像我在我的問題中所說的,如果可能的話,我想避免在對象上使用getter和setter。有沒有其他的方法來檢測我是否將一個新的屬性賦值給像'myObj [「hello」] = world'這樣的對象? –

+0

'myObj [「hello」](world)'會滿意嗎? 'myObj [「hello」] = function(someVar){myObj._hello = someVar; someOtherProcessing();}' – soniiic

+0

@soniiic:不,因爲那樣我就不得不爲每個我想要分配的屬性創建一個函數,對吧? –

1

根據您的要求,簡短的回答是,您不可能做你想做的事。至少,還沒有。有幾種技術可以用來獲得相同的功能,而對代碼的影響最小。這是我的個人最愛之一 - 在SO的某個地方發現 - 如果我能找到,我會鏈接。

function myObj(){ 

    var _this = this; 

    // onUpdate callbacks 
    this.onBeforeUpdate = []; 
    this.onAfterUpdate = []; 

    this.UpdateProperty = function(prop, value){ 

     // execute onBeforeUpdate callbacks... 
     for (var i = 0; i < _this.onBeforeUpdate.length; i++) 
     _this.onBeforeUpdate[i](); 

     _this[prop] = value; 

     // execute onAfterUpdate callbacks... 
     for (var i = 0; i < _this.onAfterUpdate.length; i++) 
     _this.onAfterUpdate[i](); 
    }; 

} 

當然,這個例子可以作出一些自由使用原型任務的表現得更好,但你可以看到的意圖。

相關問題