奇怪的Javascript数组同步技巧?

拉平

我发现了一个奇怪的JS行为:

var myArray = [ [1] , [2] , [3] ];

var myArrayCopy = [];

myArrayCopy.push( myArray[1] );

alert( myArrayCopy ); // 2, as expected.

myArrayCopy[0][0] = 'foo';

alert( myArrayCopy ); // 'foo', as expected.

alert( myArray ); // 1, foo, 3  =  WTF ? :)

参见演示

请注意,如果我们直接推送值而不是数组,这将不起作用。

对我来说,这就像将数组推入数组,以某种方式进行转换,就好像我们仅推导对这些数组的引用,而不是推入副本一样(这不是人们期望的行为,如果我错了,请更正)。

有人可以解释为什么吗?

天顶

混叠。

您正在myArrayCopy引用包含在中的现有对象(数组)myArray因此,在修改该数组时,您正在修改从上述两个数组引用的实际对象。

请注意,在JavaScript中传递对象时,它们不会被复制,而是传递对实例的引用,并在接收者的范围内对其进行修改,这也会导致调用者范围内的对象也被修改。该规则有一些明显的例外(例如,原始类型不是对象的示例,或者是它们在写入时实际复制的字符串的示例,依此类推),但让我们集中讨论您的问题。

考虑到数组是一个对象,在以下示例中发生的操作相同,但从我的角度来看,它更加清晰:

var o = { "foo": " bar" };
myArray[0] = o;
myArrayCopy[0] = myArray[0];
o.foo = "nolongerbar";

它返回myArrayCopy[0].foo什么?那又怎样myArray[0].foo呢?

在大多数OO语言中,这被称为别名,无论如何,当您处理对象的引用时,这是一个常见错误。

编辑

哦,无论如何,这不是同步技巧,通常是烦人的bug背后的原因。:-)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章