【问题标题】:Why does changing one array alters the other?为什么改变一个数组会改变另一个数组?
【发布时间】:2011-05-12 08:38:44
【问题描述】:

考虑一下这段 javascript 代码:

var a = [1, 2, 3],
    b = a;

b[1] = 3;

a; // a === [1, 3, 3] wtf!?

为什么当我更新“b[1]”时“a”会改变?我已经在 Firefox 和 Chrome 中对其进行了测试。例如,这不会发生在一个简单的数字上。这是预期的行为吗?

var a = 1,
    b = a;

b = 3;

a; // a === 1 phew!

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    因为数组是对存储它们的实际位置的引用。

    【讨论】:

    • 变量是对其对象存储位置的引用,这里的问题更多
    • @Gareth 我就是这么说的......数组是一个变量,当你使用它们时你对数组的看法不是它们的存储方式,而是它们的使用方式(即作为变量)。
    【解决方案2】:

    因为“a”和“b”引用同一个数组。没有两个;将“a”的值分配给“b”会将引用分配给数组,不是数组的副本

    当您分配数字时,您处理的是原始类型。即使在 Number 实例上也没有更新值的方法。

    您可以在 Date 实例中看到相同的“它们指向同一个对象”行为:

    var d1 = new Date(), d2 = d1;
    d1.setMonth(11); d1.setDate(25);
    alert(d2.toString()); // alerts Christmas day
    

    【讨论】:

      【解决方案3】:

      它是同一个数组(因为它是一个对象,所以它是同一个引用),您需要创建一个副本以使用.slice() 分别操作它们(这会创建一个新数组,其中复制了第一级的元素),像这样:

      var a = [1, 2, 3],
          b = a.slice();
      
      b[1] = 3;
      
      a; // a === [1, 2, 3]
      

      【讨论】:

      • 你应该解释为什么你使用切片......并且还要提到副本只有一层深度
      • @Juan - 我直接提供了一些最佳文档的链接以获得完整的解释,但在这里添加了更多内容。
      • 感谢 .slice() 解决方案!这将被大量使用:)
      • 我一直用Array.concat
      【解决方案4】:

      除了其他答案,如果你想要一个数组的副本,一种方法是使用 slice 方法:

      var b = a.slice(0)
      

      【讨论】:

      • 其实这是一个绝妙的补充!
      【解决方案5】:

      语句x = y是这里唯一的特殊语句,它的意思是“将变量x指向对象y

      几乎所有其他操作都是更改x引用的对象的操作

      b = a;
      b[1] = 3;
      

      因此,您的第一条语句将变量 b 指向数组,也称为 a

      您的第二条语句更改了b(以及a)指向的数组

      【讨论】:

        【解决方案6】:

        分配一个数组不会创建一个新数组,它只是对同一个数组的引用。分配给新变量时会复制数字和布尔值。

        【讨论】:

          【解决方案7】:

          所有 Javascript 对象都通过引用传递 - 您需要复制整个对象,而不是分配它。

          对于数组,这很简单 - 只需执行以下操作:

          var a = [1, 2, 3];
          var b = a.slice(0);
          

          其中slice(0) 返回从偏移量0 到数组末尾的数组。

          This link 有更多信息。

          【讨论】:

            【解决方案8】:

            Value typesReference types 之间存在差异。

            基本上,值类型直接存储在计算机“堆栈”上,这意味着您实际上拥有“值”,而不是所谓的指针/引用。

            另一方面,引用类型不保存对象/变量的实际值,而是指向(引用)您可以找到该值的位置。

            因此,当您说“我的参考类型 B 指向参考类型 A 所指向的内容”时,实际上有两个变量指向同一个方向,当您与其中任何一个进行交互并更改某些内容时,两者都将指向改变了地方,因为从一开始就指向同一个地方。

            在另一种情况下,您说“嘿,将变量 A 中的值复制到变量 B”,因此您将值放在不同的位置,这意味着对其中任何一个的任何更改都不会影响另一个。

            【讨论】:

            • 只是为了纠正你的最后一点。当值为数字时,分配不同。第二个示例不同的原因是因为 change (b = 3) 是另一个赋值,之前它对原始对象进行了可变更改
            • @Gareth,这不是我说的吗?赋值会复制值,因此当您更改它时,它不会影响“a”。
            • 抱歉,我在第一次阅读时得到的印象是您将基元和其他对象区分为右值。我的坏
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多