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

如何检测属性何时添加到JavaScript对象?,javascript,Javascript,这个问题与正在讨论的检测已声明属性何时更改的方法不同 您可以计算对象的属性,并查看是否与上次检查时发生了更改: 这是一个粗糙的解决方法,如果您在语言中找不到对该功能的适当支持,可以使用它。从技术上讲,这是可能的,但因为我所知道的所有当前JS实现都是单线程的,所以它不会非常优雅。我唯一能想到的就是暴力间歇: var obj = {}; obj.a = 1; // fire event, property "a" added var checkObj=(函数(watchObj) { var i

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

您可以计算对象的属性,并查看是否与上次检查时发生了更改:


这是一个粗糙的解决方法,如果您在语言中找不到对该功能的适当支持,可以使用它。

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

var obj = {};
obj.a = 1; // fire event, property "a" added 
var checkObj=(函数(watchObj)
{
var initialMap={},allProps=[],prop;
用于(watchObj中的道具)
{
if(watchObj.hasOwnProperty(道具))
{//make tracer object:基本上克隆它
初始映射[prop]=watchObj[prop];
allProps.push(prop);//保留数组映射器
}
}
返回函数()
{
var currentProps=[];
用于(watchObj中的道具)
{
if(watchObj.hasOwnProperty(道具))
{//再次迭代对象,比较
if(watchObj[prop]!==初始映射[prop])
{//类型和值检查!
log(initialMap[prop]+'=>'watchObj[prop]);
//发现差异,以你认为合适的方式处理
}
当前道具推送(道具);
}
}
//我们还没做完!
if(当前属性长度<所有属性长度)
{
log(“删除了某些道具”);
//循环遍历数组以找出哪一个
}
};
})(someObjectToTrack);
var watchInterval=setInterval(checkObj,100)//每0.1秒检查一次?
这允许你在一定程度上跟踪一个对象,但同样,10秒的速度要做很多工作。谁知道呢,也许物体在两次间隔之间也会发生几次变化。
总之,我觉得这是一种不太理想的方法。。。也许比较
JSON.stringify
对象的字符串常量更容易,但这确实意味着缺少函数和原型属性(尽管我在本例中过滤掉了它们)

我曾经考虑过做一些类似的事情,但最终只是使用我的事件处理程序来更改相关对象,以检查是否有任何更改

或者,您也可以尝试创建一个domeElement,并将一个
onchange
侦听器附加到该元素上。。。遗憾的是,函数/方法可能很难跟踪,但至少不会像上面的代码那样降低脚本的速度

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

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?
在set()方法中,与设置间隔和定期扫描以检查更改相比,您现在能够以相当高的性能查看每个更改发生的位置


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

当前ECMAScript标准中没有任何内容,但下一个标准可能会实现一个名为
Proxy
的功能,该功能将提供此功能。Firefox已实现此功能。可能重复的相关:-仅适用于选定的properties@Bergi:这两篇文章都提到了检测已声明的给定JavaScript对象的属性更改的方法。接受的答案的LIB(WATE.JS或更新的MultGETStudio.js)允许您只调用一个方法来查看JavaScript对象的属性(因此这里是一个方便的事情),但是这个LIB没有考虑“当您为这个对象添加新属性和/或改变它时,将不会调用监视器”(取自Wael.js GIST)。我想检测JavaScript对象何时添加了新属性(检测新属性的值变化排在第二位)。@Schole:不,关于检测对象上任何属性变化的重复交易,我明白你的意思,但是你怎么知道何时计算属性的数量?运行循环是不可接受的,尤其是在浏览器环境中。setInterval()以适合您需要的时间间隔为准。次优情况下,您可能有很多对象,设置setInterval()并运行函数计算属性,还可以选择确定添加了哪些属性,每秒钟几次,听起来都不健康。此外,setInterval()显然没有在浏览器中阻塞,但是在setInterval()上注册的函数的执行可能会被推迟。投票结果是:这很容易适应@Elias Van Ootegem的答案。只需选中
object.keys(object.length
,而不是
for(var key in object)
循环。为什么@Nelson的答案应该被否决???删除obj.prop1;obj.prop2='xyz';计数保持不变。
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}]}}