将对象推入数组的Javascript会更改整个数组

时间:2012-06-26 23:07:15

标签: javascript arrays object

我正在使用特定的游戏制作框架,但我认为这个问题适用于javascript

我试图制作一个叙述剧本,以便玩家可以看到“兽人击中你”。在他的屏幕底部。我想一次显示最后4条消息,并且可能允许玩家回顾日志中的30-50条消息。为此,我设置了对象和一个数组来将对象推入。

所以我最初设置了一些这样的变量......

servermessage: {"color1":"yellow", "color2":"white", "message1":"", "message2":""},
servermessagelist: new Array(),

当我通过操作servermessage.color1 ... .message1等对事件调用的不同数据多次使用此命令(下面)时...

servermessagelist.push(servermessage)

它用整个数据的副本覆盖整个数组......任何想法为什么或我能做些什么呢。

因此,如果我按color1“RED”和message1“Rover”..数据是正确的,那么如果我推 color1“yellow”和message1“Bus”数据是.color1的两个副本:“yellow”.message1:“Bus”

8 个答案:

答案 0 :(得分:20)

当您将servermessage推入servermessagelist时,您实际上(或多或少)推送对该对象的引用。因此,对servermessage所做的任何更改都会反映在您引用它的任何位置。听起来你想做的就是将对象的克隆推送到列表中。

声明一个函数如下:

function cloneMessage(servermessage) {
    var clone ={};
    for( var key in servermessage ){
        if(servermessage.hasOwnProperty(key)) //ensure not adding inherited props
            clone[key]=servermessage[key];
    }
    return clone;
}

然后,每当您想要将消息推送到列表中时,请执行以下操作:

servermessagelist.push( cloneMessage(servermessage) );

答案 1 :(得分:3)

将对象添加到数组时,它只是对添加的对象的引用。通过将对象添加到数组中不会复制该对象。因此,当您稍后更改对象并再次将其添加到数组时,您只需要一个包含对同一对象的多个引用的数组。

为数组的每次添加创建一个新对象:

servermessage = {"color1":"yellow", "color2":"white", "message1":"", "message2":""};
servermessagelist.push(servermessage);
servermessage = {"color1":"green", "color2":"red", "message1":"", "message2":"nice work"};
servermessagelist.push(servermessage);

答案 2 :(得分:1)

servermessagelist:new Array()在每次执行时清空数组。最初初始化阵列时只执行一次该代码。

答案 3 :(得分:1)

我也有同样的问题。我有点复杂的对象,我正在推进阵列。我做了什么;我使用JSON.stringify()将JSON对象转换为String,并将其推送到数组。

当它从数组返回时,我只是使用JSON.parse()将该String转换为JSON对象。

这对我来说很好,虽然它有点更圆的解决方案。 发布在这里如果你们有其他选择

答案 4 :(得分:1)

此解决方案也可用于包含嵌套键的对象。

在推送之前,通过

对obj进行字符串化
Promise.resolve.call(1)

当您使用时,解析依据

JSON.stringify(obj)

答案 5 :(得分:1)

有两种方法可以在将对象推入数组之前使用深度复制对象。 1.通过对象方法创建新对象,然后将其推送。

servermessagelist = []; 
servermessagelist.push(Object.assign({}, servermessage));
  1. 通过JSON严格方法创建对象的新引用,并使用解析方法进行推送。

    servermessagelist = []; servermessagelist.push(JSON.parse(JSON.stringify(servermessage));

此方法对嵌套对象很有用。

答案 6 :(得分:0)

我不知道为什么尚未建议使用JSON方法。 您可以先对对象进行字符串化,然后再次对其进行解析以获得该对象的副本。

let uniqueArr = [];
let referencesArr = [];
let obj = {a: 1, b:2};

uniqueArr.push(JSON.parse(JSON.stringify(obj)));
referencesArr.push(obj);

obj.a = 3;
obj.c = 5;
uniqueArr.push(JSON.parse(JSON.stringify(obj)));
referencesArr.push(obj);

//You can see the differences in the console logs
console.log(uniqueArr);
console.log(referencesArr);

答案 7 :(得分:0)

如上所述,最简单的方法是将其设置为字符串并将其转换回JSON对象。

this.<JSONObjectArray>.push(JSON.parse(JSON.stringify(<JSONObject>)));

像魅力一样工作。