Javascript数组项被覆盖

时间:2017-04-13 16:33:24

标签: javascript arrays node.js

我有一个包含以下代码的函数:

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 个答案:

答案 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);