迭代时的数组修改

时间:2015-11-26 10:52:12

标签: javascript arrays node.js

在迭代数组时尝试修改当前项时,修改失败。以下是示例代码。

var s_arr = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}];
var arr = [];

for(var i in s_arr) {

  if(s_arr[i].a == 5) {

    s_arr[i].b = 0;
    console.log('First modification: ' +JSON.stringify(s_arr[i]));
    arr.push(s_arr[i]);

    s_arr[i].b = 9;
    console.log('Second modification: ' +JSON.stringify(s_arr[i]));
    arr.push(s_arr[i]);
  }

}

console.log('Final: ' +JSON.stringify(arr));

运行上述脚本node test.js后,结果如下。

First modification: {"a":5,"b":0}
Second modification: {"a":5,"b":9}
Final: [{"a":5,"b":9},{"a":5,"b":9}]

预期结果如下。

First modification: {"a":5,"b":0}
Second modification: {"a":5,"b":9}
Final: [{"a":5,"b":0},{"a":5,"b":9}]

然而,在迭代时添加新对象&分配当前项(对象)的每个值可以广泛使用。

var s_arr = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}];
var arr = [];

for(var i in s_arr) {

  if(s_arr[i].a == 5) {

    s_arr[i].b = 9;
    console.log('Second modification: ' +JSON.stringify(s_arr[i]));
    arr.push(s_arr[i]);

    var a = {};
    a.a = s_arr[i].a;
    a.b = 0;
    arr.push(a);

    var b = {};
    b.a = s_arr[i].a;
    b.b = 9;
    arr.push(b);
  }

}

console.log('Final: ' +JSON.stringify(arr));

以下是修改过的脚本的结果。

Final: [{"a":5,"b":0},{"a":5,"b":9}]

为什么运行时的第一个脚本显示对象权限的修改,但是最终数组显示哪些包含修改后的对象不符合预期?

1 个答案:

答案 0 :(得分:2)

对象总是通过JS中的引用传递。

arr.push(s_arr[i]);不会创建对象的副本,只是在arr数组中保存对它的引用;
因此,您将在数组中看到对象内的任何更改。

您应该明确克隆您的对象以防止更改  例如,您可以使用serialize-deserialize对:

arr.push(JSON.parse(JSON.stringify(s_arr[i])));

你的

var a = {};
a.a = s_arr[i].a;
a.b = 0;
arr.push(a);

也会起作用,因为你在这里创建了新的对象实例,并使用仅标量属性来填充它。