JavaScript循环正在改变数据的源数组以及结果 - 为什么会这样?

时间:2011-03-21 10:26:10

标签: javascript arrays loops operator-keyword

我完全感到困惑。我有一个包含全局“散列”数字数组(在objectA中)的对象,它在循环中引用,将数字组合成一个新系列(在objectB中)。

var objectB = objectA[arrActive[0]]; 
for (i=1; i<arrActive.length; i++) {    
    var _this = arrActive[i];
    for (x=0; x<objectB.length; x++) {  
    objectB[x][1] += objectA[_this][x][1];  
    }
}

奇怪的是objectA(源数组)中的值在循环期间递增 - 但为什么呢?据我所知,我只是从objectA读取来写入objectB!

这很令人沮丧,因为每次调用该函数时,数字都会进一步膨胀!

关于JSFiddle的工作示例在这里:http://jsfiddle.net/ZbWGH/ - 我是否完全误解了+ =运算符?我确信这是一个很容易理解的问题。

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

您在名为objectA['ONE']的变量中引用了实例objectB - 该变量的任何更改都会改变实际值。

相反,您可能有兴趣将数组的克隆或“干净副本”转换为objectB,这样就不会更改原始数组。

执行此操作的简单功能是:

function CopyArray(arr) {
    var clone = [];
    for (var i = 0; i < arr.length; i++) {
        var subArray = [];
        for (var j = 0; j < arr[i].length; j++)
            subArray.push(arr[i][j]);
        clone.push(subArray);
    }
    return clone;
}

使用它:

var objectB = CopyArray(objectA[arrActive[0]]); 

更新了jsFiddle:http://jsfiddle.net/yahavbr/ZbWGH/1/

答案 1 :(得分:0)

更多A += BA = A + B类似,因此您修改了objectA。

答案 2 :(得分:0)

你知道C吗? C中的引用/指针是理解Javascript中的komplex变量的好方法。 “Komplex”意味着所有不是Number,String,Boolean - 其他一切都是“对象”。 komplex类型(对象)的变量确实像指针一样。如果你知道“按引用调用”和“按值调用”的概念,在Javascript中它既不是,也就是:如果你给函数提供对象,那么“指针”本身就是按值调用,但是值是对它的引用对象(实际上是存储对象的堆上的区域,即使JS程序员不像C / C ++那样处理堆,它仍然是存储东西的地方)。例如:

function fn (a) {
  //changing the argument itself does NOT change the original object
  a = null;
  //but changing its properties does:
  a.foo = 42;
}

var o = { foo:1, bar:2 };

fn(o);

所以现在应该清楚为什么你需要克隆一个对象,如果你想要真正的“按值调用”。这个实现是为JS选择的,因为否则每次使用非基本类型调用函数时都必须复制堆,并且99%的时间都不是必需的。函数式编程的“真正”精神当然是纯粹的价值观,在这里我们看到了理论上的实际生活(性能和内存使用)考虑因素:)