2

我有一个每 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)

4

1 回答 1

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 )。

与此相比,您的解决方案可能看起来不那么复杂(至少在代码方面)。我建议使用一些JS性能测试来找出,这更合理。JSON.stringify()并不总是本机支持,因此它可能会做同样复杂的事情(并且消耗资源),就像我提到的替代解决方案一样。

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

另一种选择是重建您的脚本并使用例如。用于将对象标记为由用户输入更改的标志。这将为您节省每秒处理整个对象的时间,并可能带来巨大的效率提升。

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

  1. 每当用户更改对象的某些部分时,在您的用户输入处理程序中设置标志,
  2. 或者,您可以首先将特定值与原始对象进行比较(如果用户快速更改它然后恢复更改,只需将该值标记为未更改),
  3. 为了限制更改对象的处理,您甚至可以标记哪些属性已更改(因此您只处理这些属性,不处理其他),

要实现此解决方案的一部分,您甚至可以使用JavaScript setter 和 getter,如 John Resig 所述

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

于 2013-04-07T01:06:42.397 回答