考虑JavaScript代码的这一点点:为什么更改一个数组会改变另一个数组?
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
为什么 “” 改变,当我更新 “B [1]”?我已经在Firefox和Chrome中测试过它。例如,这不会发生在简单的数字上。这是预期的行为?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!
考虑JavaScript代码的这一点点:为什么更改一个数组会改变另一个数组?
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
为什么 “” 改变,当我更新 “B [1]”?我已经在Firefox和Chrome中测试过它。例如,这不会发生在简单的数字上。这是预期的行为?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!
因为“a”和“b”参照相同的阵列。他们中没有两个;将“a”的值分配给“b”将参考分配给阵列而不是 a 拷贝阵列。
当您分配号码时,您正在处理原始类型。即使在Number实例中,也没有办法更新该值。
你可以看到相同的“他们指向同一个对象”与Date实例的行为:
var d1 = new Date(), d2 = d1;
d1.setMonth(11); d1.setDate(25);
alert(d2.toString()); // alerts Christmas day
因为数组是引用它们存储的实际位置。
变量是指存储对象的地方,更多的问题在这里 – Gareth 2010-11-18 23:16:59
@Gareth这就是我所说的......数组是一个变量,当你使用数组的时候你认为数组的方式不是用它们是如何存储的,但是它们是如何使用的(作为变量)。 – 2010-11-18 23:21:44
这是相同的阵列(因为它是一个对象,它是相同的),你需要创建副本,分别操纵他们使用.slice()
(这将创建与复制的第一级元素的数组),就像这样:
var a = [1, 2, 3],
b = a.slice();
b[1] = 3;
a; // a === [1, 2, 3]
你应该解释为什么你使用切片...并且还提到副本只有一个深度 – 2010-11-18 23:16:37
@Juan - 我提供了一个直接链接到一些最好的文档可用于完整的解释,但在这里增加了一点。 – 2010-11-18 23:17:25
感谢.slice()解决方案!这将被用于很多:) – 2010-11-18 23:33:47
除了其他的答案,如果你想要的副本数组,一种方法是使用分片方法:
var b = a.slice(0)
声明x = y
是这里唯一特殊的一个,它的意思是“在对象y
点变量x
。
几乎所有其他的操作是由x
b = a;
b[1] = 3;
改变所指的对象的操作所以,你的第一条语句点在数组变量b
也被称为a
你的第二个语句更改b
指向的数组(以及a
)
指定数组不会创建新数组,它只是对同一个数组的引用。数字和布尔值在分配给新变量时被复制。
所有Javascript对象都通过引用传递 - 您需要复制整个对象,而不是分配它。
对于数组,这将是简单的 - 只是这样做:
var a = [1, 2, 3];
var b = a.slice(0);
其中slice(0)
返回从偏移0
到数组末尾的数组。
This link有更多信息。
有Value types和Reference types之间的差。
Basicly Value类型直接存储在计算机“堆栈”上,这意味着您实际上具有“值”而不是所谓的指针/参考。
另一方面,引用类型不包含对象/变量的实际值,而是指向(引用)到您可以找到值的位置。
因此,当您说“我的参考类型B指向参考类型A指向的内容”时,您实际上有两个变量指向相同的方向,当您与其中任何一个进行交互并更改某些内容时,两者都会指向自改变的地方,因为从开始指向相同的地方。
在另一种情况下,您会说“嘿,将变量A中的值复制到变量B中”,因此您具有单独位置上的值,这意味着对其中任何一个的任何更改都不会影响其他值。
感谢您的好解释!我之前没有遇到过... – 2010-11-18 23:36:50