Javascript:forEach() 循环填充数组 - 闭包问题

标签 javascript arrays loops foreach closures

假设我们有一个对象数组,例如:

var fruits = [ {name:"banana", weight:150},{name:"apple", weight:95},{name:"orange", weight:160},{name:"kiwi", weight:80} ];

我想用“fruits”数组中重量大于 100 的项目填充“heavy_fruits”数组。这是我的代码:

var heavy_fruits = [];
myfruit = {};

fruits.forEach(function(item,index) {
  if ( item.weight > 100 ) { 
    myfruit ["name"] = item.name;
    myfruit ["weight"] = item.weight;
  }

heavy_fruits.push(myfruit);
});

但是它显示: 名称:“橙色”,重量:160 名称:“橙色”,重量:160 名称:“橙色”,重量:160 名称:“橙色”,重量:160

我知道这是混合闭包和循环的问题...但我读了一篇文章 ( http://zsoltfabok.com/blog/2012/08/javascript-foreach/ ) 解释说我会使用 forEach 循环而不是经典的 for 循环来避免此类问题。

我知道我可以使用像filter()这样的数组方法,但我是故意问的,因为我实际上遇到了一个更大的函数的麻烦,我无法在这里公开......所以我试图总结并用“水果”简化我的问题描述。

最佳答案

var heavy_fruits = [];
myfruit = {}; // here's your object

fruits.forEach(function(item,index) {
    if ( item.weight > 100 ) { 
        myfruit ["name"] = item.name;
        myfruit ["weight"] = item.weight; // you modify it's properties
    }

    heavy_fruits.push(myfruit); // you push it to the array
});

最终得到一个数组[myfruit, myfruit, myfruit, myfruit]

现在,如果您在代码中的任何位置修改 myfruit,则更改将在每次出现 myfruit 时可见。为什么?

因为您正在修改对象的引用。 在此示例中,您的数组仅存储对象的副本。如果你改变其中之一,每一项都会改变,因为它们都是引用。

要在每次迭代中解决此问题,您应该创建一个新对象,然后对其执行一些操作。

顺便说一句,事实上,您的 if 可能是这样的:

if ( item.weight > 100 ) { 
    heavy_fruits.push(item); // if `item` only has `name` and `weight` properties
}

关于Javascript:forEach() 循环填充数组 - 闭包问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38855351/

相关文章:

java - 如何通过循环将字符串添加到字符串数组列表

javascript - Firefox 6 的 Event.target 问题

javascript - 为什么这个else语句没有被触发?

Python 斐波那契数列 - 不同的 while 循环

c - 多维列移位中的数组索引错误(使用指针)

arrays - 在 Julia 中旋转非位数组

MySQL游标循环中的语法错误

javascript - JS : window. open - 如何设置 Open Sans 字体?

javascript - 粘性导航在第一次滚动时进行奇怪的跳跃(固定位置)

arrays - 按数组的最后一个元素排序 mongodb