2017-04-13 140 views
0

我有一個包含以下代碼的函數:JavaScript數組項被覆蓋

stores = []; 
console.log('in stores d.length is ', districts.length); 
districts.forEach(function (dis) { 
    dis.store.forEach(function(store) { 
     store.structure = dis.structure; 
     store.structure.dis = dis.district_nbr; 
     store.structure.sto = store.store_nbr; 
     //store.message = getMessage(store.structure); 
     console.log('store st is ', store.structure); 
     stores.push(store); 
    }); 
}); 
stores.forEach(function (s) { 
    console.log("after set Master this is stores ", s.structure); 
}) 

作爲環路去,我初始化爲每個商店對象structure開始作爲從父具有DIS對象的結構幾個領域,並已被驗證爲正確的。然後我在結構對象中添加一些額外的字段來計算區號和存儲號。每個dis對象都有一組獨特的商店。

嵌套for循環中的console.log顯示商店的正確結構。但是,當我在事實後打印這些商品時,商店的所有商品都有循環中的最終區號和循環中的最終商店編號,而不是各自的正確值。

問題:在Array.push()中發生了什麼,我沒有意識到通過重擊之外的東西?我認爲我真正的問題是我錯過了什麼?

回答

3

您需要克隆dis.structure以避免在循環的每次迭代中修改同一對象。

function clone(obj) { 
    return JSON.parse(JSON.stringify(obj)); 
} 

stores = []; 
console.log('in stores d.length is ', districts.length); 
districts.forEach(function (dis) { 
    dis.store.forEach(function(store) { 
     store.structure = clone(dis.structure); 
     store.structure.dis = dis.district_nbr; 
     store.structure.sto = store.store_nbr; 
     //store.message = getMessage(store.structure); 
     console.log('store st is ', store.structure); 
     stores.push(store); 
    }); 
}); 
stores.forEach(function (s) { 
    console.log("after set Master this is stores ", s.structure); 
}) 

有關深度克隆對象的更多信息,請參閱this answer on stack overflow

1

您的dis.store的商品與stores商品相同,因爲您的stores的商品不是價值觀,而是參考。所以你把相同的引用放入2個不同的數組中。如果您從一個參考項目更改項目,它也將更新爲另一個參考項目。

你需要將它們與Object.assign複製,但要注意它只能複製第一級項目 替換該行store.structure = dis.structure; store.structure = Object.assign({}, dis.structure);

2

的問題是,當你設置store.structure = dis.structurestore.structure是現在參考dis.structure,不是副本。

這意味着,每次您突變store.structure時,您實際上都在變異dis.structure