迭代时修改数组
Array modification while iteration
在迭代数组时尝试修改当前项时,修改失败。下面是示例代码。
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}]
为什么运行时的第一个脚本显示对象权限的修改,而最后一个数组显示由修改后的对象组成的内容与预期不同?
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);
也会起作用,因为您在这里创建新的对象实例,并使用仅标量属性来填充它。
相关文章:
- 使用Underscore.js修改json数组中所选元素的更有效方法
- 修改d3.js圆环图以读取json数组
- 迭代和修改Firebase数组会导致未定义
- 将修改后的数组作为参数传递给函数
- JavaScript:如何在迭代过程中修改数组中的值
- JavaScript:不修改实际数组的函数
- 修改后的原始数组值
- 修改隐藏输入中的json数组
- JavaScript-我可以用for循环中修改的属性将新结构推送到数组中吗
- 修改输入中的数组,然后返回输出
- 对JSON格式的对象数组进行迭代,并对其进行修改和扩展,最好使用Undercore.js
- Polymer:当数组中的对象被外部代码修改时,更新dom重复元素
- 如何过滤/修改主干集合本身,而不是获取新数组
- 我如何修改它以使用数组中的所有项目
- 在javascript中,如何将相同的对象两次推送到一个数组中,并进行一些修改而不覆盖数组
- Emscripten:调用修改数组元素的 C 函数
- JavaScript 修改 URL 参数数组
- 为什么数组上的 js 映射会修改原始数组
- JS多维数组修改值
- 通过包含引用的数组修改特定属性