2017-04-13 138 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