我有一个包含以下代码的函数:
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()中发生了什么事情,我通过不正常的事情不知道这一点?我认为我真正的问题是我错过了什么?
答案 0 :(得分: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 :(得分:2)
问题在于,当您设置store.structure = dis.structure
时,store.structure
现在是引用到dis.structure
,而不是副本。
这意味着每次你改变store.structure
时,你实际上是在改变dis.structure
。
答案 2 :(得分:1)
您的dis.store
项与stores
项相同,因为您的stores
项不是值,而是参考。所以你将相同的引用放入2个不同的数组中。如果您从一个引用更改项目,它也将更新为另一个引用。
您需要使用Object.assign
复制它们,但要注意它只会复制第一级项目
用此替换此行 store.structure = dis.structure;
store.structure = Object.assign({}, dis.structure);