【问题标题】:New objects get overwritten when being added to an array新对象在添加到数组时被覆盖
【发布时间】:2025-12-10 04:55:02
【问题描述】:

这里的新手......要友善。

我有一个空对象,它将被推入一个数组。

listView = {};

我给它添加属性。

listView.code = code;
listView.description = description;

我将结果对象推入一个数组。

listy.push(listView);

每次我在第 2 步中输入新选择时,它都会覆盖对象,而不是将新的对象属性添加到数组中。它还将索引加一,所以它只是重复......

[{"code":"I77.812","description":"Thoracoabdominal Aortic Ectasia"}]
[{"code":"I77.811","description":"Abdominal Aortic Ectasia"},{"code":"I77.811","description":"Abdominal Aortic Ectasia"}]
[{"code":"I06.1","description":"Rheumatic aortic insufficiency"},{"code":"I06.1","description":"Rheumatic aortic insufficiency"},{"code":"I06.1","description":"Rheumatic aortic insufficiency"}]

数组应该包含三个不同的对象。但相反,它具有新添加的三个副本...

我应该如何添加新的选择对象,以免它们被覆盖?

【问题讨论】:

  • 如何添加三个新对象?你能把你用来做那件事的代码放上去吗?
  • 第一个错误:var listView= {};
  • javascript 对象通过引用传递。所以一旦列表对象的值改变了。它也反映在 listy 数组中。您可以每次在循环内创建列表对象并作为 var list = {},并将列表对象也推送到循环内。

标签: javascript arrays object


【解决方案1】:

您总是添加对同一个对象的引用并更改同一个对象,而不是添加新对象。看到这个:

var a = [];
var o = {};
for (var i = 0; i < 5; i++) {
  o.id = i;
  a.push(o);
}
a
// => [{"id":4},{"id":4},{"id":4},{"id":4},{"id":4}]

但是

var a = [];
for (var i = 0; i < 5; i++) {
  var o = {};
  o.id = i;
  a.push(o);
}
a
// => [{"id":0},{"id":1},{"id":2},{"id":3},{"id":4}]

不同之处在于,第二个代码总是生成一个与数组中已有的所有其他对象不同的新对象。

作为一个隐喻,想象一个戏剧导演在选角。他转向演员,说:“你……你将成为罗密欧。”。然后他看着同一个演员,说:“你……你将成为Mercutio。来,Mercutio,拿起这把剑。罗密欧……谁让你拿剑的?!?”完全没有意识到,如果罗密欧和默库西奥是同一个人,如果他们中的一个拿起剑,另一个也会这样做。

【讨论】:

    【解决方案2】:

    看到你宣称自己是“新手”,我想我需要多花点时间来解释一下。当您将对象推送到数组时,您不会复制该对象。您只需告诉数组在哪里可以找到对象(引用)。如果您将同一个对象推送 3 次,则该数组只有 3 个索引可以找到相同的对象。有几种方法可以解决这个问题,最简单的方法是在循环中声明变量

    for (var i=0;i<3;i++){
        var listView = {};
        listView.id = i;
        listy.push(listView);
    }
    

    这样 listView 每次都是不同的引用。另一种方法是在推送时创建一个新对象

    listy.push({id:listView.id, description:listView.description});
    

    之所以有效,是因为简单的变量被“复制”到数组中而不被引用。

    【讨论】:

      【解决方案3】:

      您对对象属性的分配只是替换现有属性。当您按名称推送数组中的对象时,您推送的是对该对象的引用而不是值。这就是为什么数组中的所有元素都相同的原因。每次推送时都需要创建一个新对象。像这样的东西应该适合你。

      listy.push({code:code, description:description});
      

      【讨论】:

      • 感谢您的解释!需要“创建一个新对象”是完全有意义的!
      【解决方案4】:

      试试这个:

      listy.push({
          code:listView.code,
          description : listView.description
      })
      

      在我的代码中,我使用了按值传递。

      在您的代码中,您使用的是通过引用传递的对象。

      您一次又一次地添加 same reference,所以最后您将获得一个包含 same object 的所有值的数组。

      要了解有关按值传递和按引用传递的更多信息,您可以参考此链接:

      Pass Variables by Reference in Javascript

      【讨论】:

      • 这成功了!甚至不知道你能做到这一点!谢谢大佬!
      • 太好了!!我将通过答案进行更新以使其更清晰:)
      • 是的,它可以工作,但是首先将单个对象成员分配给一个中间对象,你会得到什么?您也可以直接在该代码中设置变量值。希望您现在了解范围问题,如 Amadan 的代码所示。这是完成作业的另一种方式,但这并不是您真正询问的内容。
      • 我完全从 Amadan 的解释中得到了范围界定问题。在我的代码中,我需要像他一样添加一个 for 循环并将对象放入其中。