Array.Push 覆盖之前的 Value Node Js

Posted

技术标签:

【中文标题】Array.Push 覆盖之前的 Value Node Js【英文标题】:Array.Push overwrites the previous Value Node Js 【发布时间】:2017-09-10 14:44:49 【问题描述】:

美好的一天。 我有一个全局数组,它必须是全局的。

var comments= [];

我有一个套接字的回调,我正在迭代它并添加值。

代码更好:

    socket.on('commentAdded', function (data) 
    if (data !== null) 
        var stringify = JSON.stringify(data);
        var json = JSON.parse(stringify);

        Object.keys(users).forEach(function (key) 
            if (key !== "null") 
                data.eachUserId = key;
                console.log("data added with id " + key + " the size of comments is " + comments.size);
                comments.push(data);
            
        );
        console.log("comment was added");
    

    socket.broadcast.emit('onCommentAdded', data);
);

在这里,我的console.Log("data added with id)... 正在正确打印所有内容,理想情况下,我想向 现有数据(即 json 数据)添加一个新值,新值的名称是 eachUserId,哪个值必须完全不同,因为我在循环中这样做,如您所见。

这就是我之后获得物品的方式。

   for (var f = 0; f < Object.keys(comments).length; f++) 
        var comment = comments[f];
        var eachUserId = comment.eachUserId;
        console.log("checking with current user id" + userId + " each user id" + eachUserId + " or each user id in [] way " + comment['eachUserId']);
        if (eachUserId === userId) 
            socket.emit('onCommentAdded', comment);
        
    

这里 eachUserId 始终是循环中添加的最后一项...我做错了什么?为什么push() 方法会覆盖每个值?

【问题讨论】:

【参考方案1】:

问题:

您的问题是当您将值分配给eachUserId 到对象data 时。您只有 1 个名为 data 的对象,并且您一遍又一遍地将同一个对象添加到数组中。但请记住,它们都指向同一个对象,当您更改该对象中的任何内容时,它会在各处反映出来

因此,当您在循环中更改 data.eachUserId = key; 时,它会更改数组中的所有项目。最后,它们都包含您分配给它的最后一个 eachUserId 值。

解决方案:

您需要克隆对象,然后将其推送到数组中。


我建议您使用lodash 库和cloneDeep 方法来创建对象的深层克隆。

var _ = require('lodash');  //require "lodash"

socket.on('commentAdded', function (data) 
    if (data !== null)         
        Object.keys(users).forEach(function (key) 
            if (key !== "null") 
                var dataClone = _.cloneDeep(data);  //create deep clone
                dataClone.eachUserId = key;         //assign "key"
                comments.push(dataClone);           //push into the array
            
        );
        console.log("comment was added");
        
    socket.broadcast.emit('onCommentAdded', data);
);

【讨论】:

太棒了!最好的解决方案,它就像一个魅力!【参考方案2】:

使用Spread Operator,已经是Stage 4 (ECMAScript)

const foo = 

const bar = ...foo

foo.a = 1;
bar.a = 10;

console.log(foo) // a : 1
console.log(bar) // a : 10

【讨论】:

【参考方案3】:

您确定您的comments 包含所需的数据吗?将其包裹在 closure 中,因此它会创建一个 new scope for each iteration 并传递正确的数据。

for (var f = 0; f < Object.keys(comments).length; f++) 
       (function(f)
          var comment = comments[f];
          var eachUserId = comment.eachUserId;
          console.log("checking with current user id" + userId + " each user id" + eachUserId + " or each user id in [] way " + comment['eachUserId']);
          if (eachUserId === userId) 
             socket.emit('onCommentAdded', comment);
          
       )(f))
    

【讨论】:

这不是我想要的...我只是想将数据添加到现有的 json 对象并将其插入到数组中,这不能解决我的问题

以上是关于Array.Push 覆盖之前的 Value Node Js的主要内容,如果未能解决你的问题,请参考以下文章

RX学习笔记:JavaScript数组操作

判断checkbox是否选中

sql 有重复字段的多个表查询时,数据被覆盖怎么解决?

Ruby - Array#<< 和 Array#push 之间的区别

如何使用`docker cp``--no-clobber`?从Docker容器复制文件,但如果目标已经存在,则不覆盖]]

Array.push(Object) 插入对象数组