如何检测何时将属性添加到JavaScript对象?

时间:2012-10-01 18:02:14

标签: javascript

var obj = {};
obj.a = 1; // fire event, property "a" added 

这个问题与this one不同,后者正在讨论如何检测已声明的属性何时被更改。

3 个答案:

答案 0 :(得分:0)

您可以计算对象上的属性,看看您上次检查时是否有变化:

How to efficiently count the number of keys/properties of an object in JavaScript?

这是一个粗略的解决方法,用于您无法在该语言中找到对该功能的适当支持。

答案 1 :(得分:0)

从技术上讲,这是可能的,但由于我所知道的所有当前JS实现都是单线程的,因此它不会非常优雅。我唯一能想到的就是蛮力间隔:

var checkObj = (function(watchObj)
{
    var initialMap = {},allProps = [],prop;
    for (prop in watchObj)
    {
        if (watchObj.hasOwnProperty(prop))
        {//make tracer object: basically clone it
            initialMap[prop] = watchObj[prop];
            allProps.push(prop);//keep an array mapper
        }
    }
    return function()
    {
        var currentProps = [];
        for (prop in watchObj)
        {
            if (watchObj.hasOwnProperty(prop))
            {//iterate the object again, compare
                if (watchObj[prop] !== initialMap[prop])
                {//type andvalue check!
                    console.log(initialMap[prop] + ' => ' watchObj[prop]);
                    //diff found, deal with it whichever way you see fit
                }
                currentProps.push(prop);
            }
        }
        //we're not done yet!
        if (currentProps.length < allProps.length)
        {
            console.log('some prop was deleted');
            //loop through arrays to find out which one
        }
    };
})(someObjectToTrack);
var watchInterval = setInterval(checkObj,100);//check every .1 seconds?

这允许你在某种程度上跟踪一个对象,但同样,这个10 /秒的工作要做很多工作。谁知道,也许对象在间隔之间也会多次改变。
总而言之,我觉得这是一种不那么理想的方法......也许比较字符串常量会更容易JSON.stringify'ed对象,但这确实意味着错过了函数,并且(尽管我在这个例子中将它们过滤掉了)原型属性。

我曾考虑过在某个方面做类似的事情,但最终只是使用我的事件处理程序来更改相关对象以检查是否有任何更改。
或者,你也可以尝试创建一个DOMElement,并附加一个onchange监听器......遗憾的是,功能/方法可能会很难跟踪,但至少它不会减慢你的脚本速度如上面的代码将。

答案 2 :(得分:0)

如果性能很重要并且您可以控制更改对象的代码,请创建一个控件类来修改对象,例如。

var myObj = new ObjectController({});

myObj.set('field', {});
myObj.set('field.arr', [{hello: true}]);
myObj.set('field.arr.0.hello', false);

var obj = myObj.get('field'); // obj === {field: {arr: [{hello: false}]}}

在set()方法中,与设置间隔和定期扫描以检查更改相比,您现在能够以相当高性能的方式查看每个更改的位置。

我在ForerunnerDB中做了类似但高度优化的事情。在数据库上执行CRUD操作时,会针对特定字段路径触发更改事件,从而允许在基础数据更改时更新数据绑定视图。