有没有办法检测对象的属性何时被更改?

时间:2012-05-14 13:38:14

标签: javascript oop

如何在Javascript中检测对象的属性是否已更改?我特别希望在对象上的属性数量发生变化时调用函数(无论是已获得还是失去属性)。我想避免使用方法并设置和更改对象的属性,因为这样会很快笨拙,setInterval显然不是一个选项。那么,这可能吗?


编辑:我特意寻找一种通过类似于Array对象上的length属性来获取对象属性长度的方法。我假设他们在添加或删除索引时改变了长度,但显然情况并非如此。 Javascript的原始设计者是如何管理这个的?

3 个答案:

答案 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);

答案 1 :(得分:1)

根据您的要求,简短的答案是,您无法做您想做的事情。至少,还没有。您可以使用一些技术来获得相同的功能,同时对代码的影响最小。这是我个人最喜欢的一个 - 在某处发现 - 如果我能找到,我会联系。

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]();
   };

}

当然,这个例子可以通过一些自由使用原型分配来表现得更好,但你可以看到意图。

答案 2 :(得分:1)

所以,总结一下我通过评论说的一切:ES6将提供代理,这些代理应该为“新属性”或“属性删除”等事件启用处理程序。 (尽管如此,我还没有考虑过那么多。)不幸的是,代理变成跨浏览器需要数年时间。

至于对象的length属性,你可以为它定义一个getter函数,但这会在IE8中中断,因为IE只在IE9中实现了getter。所以,这会给你一个length()方法。所以:

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

然后,确保您的对象具有此功能(作为自己的属性或继承的属性):

yourObj.length = objectLength;

YourConstructor.prototype.length = objectLength;