考虑一下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!
答案 0 :(得分:8)
因为“a”和“b”引用相同的数组。其中没有两个;将“a”的值分配给“b”会将引用分配给数组,不数组的副本。
当你分配数字时,你正在处理原始类型。即使在Number实例上也没有更新值的方法。
您可以看到相同的“他们使用日期实例指向同一个对象”行为:
var d1 = new Date(), d2 = d1;
d1.setMonth(11); d1.setDate(25);
alert(d2.toString()); // alerts Christmas day
答案 1 :(得分:7)
它是相同的数组(因为它是一个对象,它是相同的引用),你需要创建一个副本来使用.slice()
单独操作它们(它创建一个新的数组,复制的第一级元素),像这样:
var a = [1, 2, 3],
b = a.slice();
b[1] = 3;
a; // a === [1, 2, 3]
答案 2 :(得分:2)
除了其他答案,如果你想要一个数组的副本,一种方法是使用切片方法:
var b = a.slice(0)
答案 3 :(得分:1)
所有Javascript对象都通过引用传递 - 您需要复制整个对象,而不是分配它。
对于数组,这很简单 - 只需执行以下操作:
var a = [1, 2, 3];
var b = a.slice(0);
其中slice(0)
将数组从偏移0
返回到数组的末尾。
This link有更多信息。
答案 4 :(得分:1)
Value types 与 Reference types 之间存在差异。
基本值类型直接存储在计算机“堆栈”上,这意味着您实际上具有“值”而不是所谓的指针/参考。
另一方面,参考类型不保存对象/变量的实际值,而是指向(引用)您可以找到值的位置。
因此,当你说“我的参考类型B指向参考类型A指向的内容”时,你实际上有两个指向同一方向的变量,当你与它们中的任何一个交互并改变某些东西时,两者都将指向改变的地方,因为从开始就指向同一个地方。
在你的另一种情况下,你说“嘿,将变量A中的值复制到变量B”,因此你在单独的位置上有值,这意味着对它们中任何一个的任何改变都不会影响另一个。
答案 5 :(得分:0)
因为数组是对存储它们的实际位置的引用。
答案 6 :(得分:0)
声明x = y
是此处唯一的特殊声明,表示“将变量x
指向对象y
。
几乎所有其他操作都是一个更改x
b = a;
b[1] = 3;
因此,您的第一个语句将变量b
指向数组,也称为a
你的第二个陈述改变了b
指向的数组(以及a
)
答案 7 :(得分:0)
分配数组不会创建新数组,它只是对同一数组的引用。分配给新变量时会复制数字和布尔值。