1

注意:这不是使用arr.slice(0)修复此“问题”的常见数组副本“问题”的数百万重复之一

也就是说,我想了解为什么会得到这个意想不到的结果:

var oldArr = [[1,2],[3,4]];
var find = oldArr[1];

var newArr = oldArr.slice(0);
console.log(newArr.indexOf(find)); //1?

//proof that newArr is NOT referenced to oldArr
newArr[0] = "Hi";
newArr[1] = "How are you?";
console.log(oldArr+" "+newArr); //"1,2,3,4 Hi,How are you?"

jsFildde 演示

如果您替换find为以下任何替代方案,它会返回预期的-1

  • [3,4]直接使用
  • 使用可变持有[3,4]
  • 使用引用另一个数组的变量[3,4]

我找不到任何解释为什么最后三种方法与第一个示例之间有任何区别。据我所知,应该没有。

有任何想法吗?

4

2 回答 2

2

在:

[[1,2],[3,4]]

创建了三个数组对象

只有外部的被slice'd。这会导致“浅拷贝”。

考虑一下:

var a = [1,2]
var b = [3,4]
var c = [a,b]
var d = c.slice(0)
d[0] === a       // true, which means it is the /same/ object
d[0][0] = "Hi!"
a                // ["Hi!", 2]

快乐编码!

于 2012-05-05T02:45:54.197 回答
1

一切都按预期工作

indexOf通过引用而不是值搜索,因此如果两个对象不===相互,indexOf将找不到它们

在你的情况下:

var oldArr = [[1,2],[3,4]];
var find = oldArr[1];

var newArr = oldArr.slice(0);

find指向数组 [3,4];所以 newArray 包含 2 个对象(两个数组)。如果你想看看到底发生了什么,试试 find.push(5)

于 2012-05-05T02:56:47.893 回答