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

这个问题与这个问题不同,其中正在讨论检测已声明属性何时更改的方法。

4

3 回答 3

0

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

如何有效地计算 JavaScript 中对象的键/属性数?

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

于 2012-10-01T18:07:40.637 回答
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侦听器......遗憾的是,函数/方法可能难以跟踪,但至少它不会像上面的代码那样减慢您的脚本速度.

于 2012-10-01T18:25:26.603 回答
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 操作时,会针对特定字段路径触发更改事件,从而允许在其基础数据更改时更新数据绑定视图。

于 2017-03-02T10:15:51.420 回答