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

时间:2016-08-09 15:52:33

标签: javascript arrays loops foreach closures

我们假设我们有一系列对象,如:

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

我想填一个" heavy_fruits"数组与来自"水果"重量大于1的阵列>这是我的代码:

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循环来避免这种问题。 / p>

我知道我可以使用像filter()这样的数组方法,但是我故意这样说,因为我实际上遇到了一个功能更大的问题我不能在这里曝光......所以我尝试用" fruits"。

来总结和简化我的问题描述

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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时都会显示更改。为什么呢?

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

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

事实上,顺便提一下,你的if可能就是这样:

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

答案 2 :(得分:0)

较短的将使用过滤器

var heavy_fruits = fruits.filter(x => x.weight > 100);

但是,如果你真的想使用forEach就这样做

var heavy_fruits = [];
fruits.forEach(x => {if(x.weight > 100) heavy_fruits.push(x)} );