迭代时修改数组

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

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 = {}; aa = s_arr[i].a; ab = 0; arr.push(a); var b = {}; ba = s_arr[i].a; bb = 9; arr.push(b); } } console.log('Final: ' +JSON.stringify(arr)); 

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

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

为什么第一个脚本运行时显示修改对象的权利,但最终数组显示哪些是由修改对象组成是不是预期的?

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

arr.push(s_arr[i]); 不创build对象的副本,只是将其引用保存在arr数组中;
所以对象中的任何更改也会在数组中看到。

您应该显式克隆您的对象以防止更改。
例如,你可以使用serialize-deserialize对:

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

你的

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

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