Javascript 将对象推送到数组中会更改整个数组

Javascript pushing objects into array changes entire array

本文关键字:数组 Javascript 对象      更新时间:2023-09-26

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

我试图制作一个旁白脚本,以便玩家可以在屏幕底部看到"兽人击中你"。 我想一次显示最后 4 条消息,并可能允许玩家回头查看日志中的 30-50 条消息,如果他们愿意的话。 为此,我设置了对象和数组来将对象推入其中。

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

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

当我多次使用此命令(如下)时,通过操作 servermessage.color1 ... .消息1等...

servermessagelist.push(servermessage)

它用该数据的副本覆盖整个阵列...知道为什么或我能做些什么。

因此,如果我按颜色 1"RED"和消息 1"漫游者".. 数据是正确的,那么如果我推送color1"yellow"和消息 1"总线"数据是 .color1:"黄色"的两个副本 .message1:"总线"

当你把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.通过对象方法创建新对象,然后推送它。

servermessagelist = []; 
servermessagelist.push(Object.assign({}, servermessage));
  1. 通过 JSON 字符串方法创建一个新的对象引用,并使用解析方法推送它。

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

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

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

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

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

我也有同样的问题。我有一点复杂的对象,我正在推入数组。我做了什么;我使用 JSON.stringify() 将 JSON 对象转换为字符串并推送到数组中。

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

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

我不知道

为什么还没有提出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);

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

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

JSON.stringify(obj)

当您使用时,请解析

JSON.parse(obj);

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

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

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

就像一个魅力。