检测javascript中是否更改了对象

时间:2013-04-07 00:05:07

标签: javascript

我有一个每1秒调用一次的函数。

var latestObject; //this updated separately, it depends on user input so it may not be different every second
var previousObject;
function Tick(object) {
    if (latestObject !== previousObject) { //Problem is here
        previousObject = latestObject; //or here
        //do stuff with latestObject;
    }
}

但是,当更新latestObject时,它的属性会发生变化,变量不会设置为其他对象。所以previousObject和latestObject总是相等的,do stuff永远不会发生。

我能做到:

function Tick(object) {
    var latestObjectString = JSON.stringify(latestObject);
    if (latestObjectString !== previousObject) { //Problem is here
        previousObject = latestObjectString; //or here
        //do stuff with latestObject;
    }
}

但后来我每秒都在做JSON.stringify一次,这似乎效率低下,特别是因为latestObject很大,而且相当深。

将previousObject设置为latestObject的副本是不是更好,这样当latestObject上的属性发生更改时,previousObject保持不变,然后只有当对象不同时才会发生这种情况,这种情况比每秒少一次?但是不会有问题,因为copyOfObject == Object永远不会是真的吗?

(该对象主要是属性,但有一些不会改变的函数)。

(没有jQuery)

1 个答案:

答案 0 :(得分:0)

问题描述

这里的问题确实与这样的事实有关,即同一个对象被分配给两个不同的变量。即使你在一个地方改变它,另一个也改变它。

此示例显示了实际发生的事情(jsFiddle:http://jsfiddle.net/tadeck/4hFC2/):

var objA = {'a':10, 'b': 20};
var objB = objA; // same instance assigned to both names
objB.a = 30; // instance is modified, its "a" property is changed
// now, both objA.a and objB.a show "30", as objA and objB is the same instance

然而,拥有两个不同的对象也不是那么理想,因为比较它们并非易事(在此证明:http://jsfiddle.net/tadeck/GN2m4/)。

解决方案号1.用于比较对象

解决这个问题:

  1. 您需要使用两个不同的对象(例如,通过使用类似于jQuery的.extend()的解决方案来从现有对象构造新对象)。您目前使用不必要的序列化来实现该部分。
  2. 您需要以更复杂的方式对它们进行比较(相当普遍的解决方案是:https://stackoverflow.com/a/1144249/548696)。
  3. 与此相比,您的解决方案可能看起来不那么复杂(至少在代码方面)。我建议使用一些JS performance tests来找出,这更合理。 JSON.stringify()并不总是本机支持,因此它可能会做同样复杂(和资源消耗)的事情,就像我提到的替代解决方案。

    解决方案号2.用于解决检测变化的整体问题

    另一个选项是重建脚本并使用例如。用于将对象标记为由用户输入更改的标志。这样可以节省每秒处理整个对象的时间,并可以大大提高效率。

    在这种情况下你需要做的事情是:

    1. 在用户输入处理程序中,只要用户更改了对象的某些部分,就会设置标志
    2. 或者,您可以先将特定值与原始对象进行比较(如果用户已快速更改它,然后还原更改,只需将值标记为未更改),
    3. 要限制已更改对象的处理,您甚至可以标记哪些属性已更改(因此您只处理这些属性,而不是其他任何属性),
    4. 要实现此解决方案的一部分,您甚至可以使用JavaScript setters and getters, as described by John Resig

      但是,正如我所提到的,它可能需要重建你的脚本(我们还没有看到,所以我们不能说它是否有必要,或者它可以很容易地应用)。