2016-08-09 32 views
0

比方說,我們有一個像對象的數組:的Javascript:foreach()循環來填充陣列 - 關閉問題

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

我想填充從「水果」與項「heavy_fruits」陣的陣高於該重量爲> 100。這裏是我的代碼:

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循環而不是經典循環來解決這類問題。

我知道我可以使用像filter()等數組方法,但我要求的目的,因爲我實際上有一個更大的功能,我不能暴露在這裏的麻煩......所以我試圖總結和簡化我的問題描述與「水果」。

+1

'myfruit'指的是同一個對象。在'forEach'回調中移動'myfruit = {};'。我建議使用'filter'作爲'var heavy_fruits = fruits.filter(f => f.weight> 100);'。 – Tushar

+0

這不是_closure_問題,它是關於引用相同的對象。 – Tushar

+0

基本上你在做什麼是改變對象的屬性,因爲數組實際上是存儲對同一對象的引用,當你改變對象的屬性時,改變在每個引用中都是可見的。 –

回答

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時都會看到該更改。爲什麼?

因爲您正在修改對象的參考。 在這個例子中,你的數組只存儲你的對象的副本。如果你改變其中的一個,每一個都會改變,因爲它們都是參考。

爲了解決這個問題,每次迭代都應該創建一個新對象,然後在它上面做一些事情。

順便說一句,因爲事實上,你if可能僅僅是這樣的:

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

非常感謝大家花時間幫助我找到解決方案:Albzi,Tushar,Adrian和Ganga。然而,阿德里安提供瞭解決方案+我的問題的明確解釋+爲什麼它不工作+我如何解決它。我已經爲這個問題掙扎了好幾天了!問候 – nadir

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

請[edit]提供更多信息。只有代碼和「嘗試這個」的答案是[灰心](// meta.stackexchange.com/questions/196187),因爲它們不包含可搜索的內容,也不能解釋爲什麼有人應該「嘗試這個」。我們在這裏努力成爲知識的資源。 – Tushar

+0

這與所討論的代碼沒有區別。除此之外,這會給[兩個橙子陣列](https:// jsfiddle。淨/ tusharj/2x9tna7g /)比四。 – Tushar

+0

heavy_fruits.push(myfruit);出了如果範圍..這是問題 – Gangz

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)});