我发现了一个奇怪的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] 删除。
我来说两句