11

我正在使用特定的游戏制作框架,但我认为这个问题适用于 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" 的两个副本

4

8 回答 8

25

当您推入时,您实际上(或多或少)推入了对该对象的引用servermessageservermessagelist因此,所做的任何更改都会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) );
于 2012-06-26T23:11:31.880 回答
3

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

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

servermessage = {"color1":"yellow", "color2":"white", "message1":"", "message2":""};
servermessagelist.push(servermessage);
servermessage = {"color1":"green", "color2":"red", "message1":"", "message2":"nice work"};
servermessagelist.push(servermessage);
于 2012-06-26T23:14:27.123 回答
3

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

servermessagelist = []; 
servermessagelist.push(Object.assign({}, servermessage));
  1. 通过 JSON stringigy 方法创建对象的新引用,并使用 parse 方法推送它。

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

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

于 2019-08-02T09:30:05.580 回答
1

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

于 2012-06-26T23:11:09.440 回答
1

我不知道为什么还没有建议使用 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);

于 2018-08-02T16:58:27.660 回答
1

我也有同样的问题。我有一些复杂的对象要推入阵列。我做了什么; 我使用 JSON.stringify() 将 JSON 对象转换为字符串并推入数组。

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

这对我来说很好,尽管它是更全面的解决方案。在这里发帖如果你们有其他选择

于 2015-08-07T04:15:25.197 回答
1

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

在推送之前,将 obj 字符串化为

JSON.stringify(obj)

当你使用时,解析

JSON.parse(obj);
于 2019-01-19T14:16:42.627 回答
0

正如上面多次提到的,最简单的方法是将它变成一个字符串并将其转换回 JSON 对象。

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

奇迹般有效。

于 2020-02-22T19:47:05.880 回答