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

nad*_*dir 4 javascript arrays foreach closures loops

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

var fruits = [ {name:"banana", weight:150},{name:"apple", weight:95},{name:"orange", weight:160},{name:"kiwi", weight:80} ];
Run Code Online (Sandbox Code Playgroud)

我想用重量大于 100 的“fruits”数组中的项目填充“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);
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

小智 5

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
});
Run Code Online (Sandbox Code Playgroud)

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

现在,如果您修改myfruit代码中的任何地方,更改将在每次出现myfruit. 为什么?

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

要在每次迭代中解决此问题,您应该创建一个新对象,然后在其上做一些事情。

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

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

  • 非常感谢所有花时间帮助我找到解决方案的人:Albzi、Tushar、Adrian 和 Ganga。然而,阿德里安提供了解决方案+对我的问题的清晰解释+为什么它不起作用+我如何解决它。我已经为这个问题苦苦挣扎了好几天!问候 (2认同)