我对数组的理解缺少啥?

Posted

技术标签:

【中文标题】我对数组的理解缺少啥?【英文标题】:What am I missing with the understanding of Arrays?我对数组的理解缺少什么? 【发布时间】:2015-08-13 04:00:41 【问题描述】:

将数组分配给另一个变量时,传递的是引用而不是值。当您使用 == 运算符比较两个数组并返回 true

var a = [[1,2],[3,4],[5,6]];
var b = a; // b = [[1,2],[3,4],[5,6]]
var c = [].concat(a); // c = [[1,2],[3,4],[5,6]]

a == b; //true
a == c; //false

使用上述输入,当我修改数组b 时,它会改变数组a,而不是c

b.push([7,8]); // b = [[1,2],[3,4],[5,6], [7,8]]
a; //a = [[1,2],[3,4],[5,6], [7,8]]
c; //c = [[1,2],[3,4],[5,6]]

但是当我执行以下操作时,它会发生变异 c

b[0].push(5); // b = [[1,2,5],[3,4],[5,6], [7,8]]
a; //a = [[1,2,5],[3,4],[5,6], [7,8]]
c; //c = [[1,2,5],[3,4],[5,6]]

为什么会这样?这种行为发生在使用改变数组的数组方法时。

【问题讨论】:

【参考方案1】:

.concat() 进行浅拷贝。所以在这行之后:

var c = [].concat(a);

ca 引用不同的数组,但 c[0]b[0]a[0] 都引用同一个数组。

引用MDN:

concat 将对象引用复制到新数组中。原始数组和新数组都引用同一个对象。也就是说,如果修改了引用的对象,则更改对新数组和原始数组都是可见的。

【讨论】:

+1,这就是答案。您认为包含如何制作数组(或任何其他对象)的 deep 副本是个好主意吗? (jQuery .extend() 或 lodash .deepClone()?) @bardzusny 已经有很多关于 *** 的答案了。 感谢 nnnnnn,它解释了这种行为。正如@bardzusny 补充的那样,有人可以建议任何内置方法或库来对数组进行深层复制吗? @Harish - bardzusny 已经提到了两个可以进行深度复制的库。我不知道这样做的本机 JS 方法。请注意,您必须小心使用深拷贝递归算法,因为 JS 允许循环引用,因此您可能会遇到 x===x[0]true... 如果我的建议确实意味着超出了问题的范围,这里有一些应该让你满意的东西:***.com/questions/122102/…。只有“vanilla.js”的轻松深度复制我能想到的方式是:c = JSON.parse(JSON.stringify(a)),这并不完美(你丢失了日期/正则表达式/其他“特殊”对象)。

以上是关于我对数组的理解缺少啥?的主要内容,如果未能解决你的问题,请参考以下文章

我对 boost::mpi::request 缺少啥?测试似乎改变了状态

我在 XMLHttpRequest 中缺少啥?

缺少模板 - 模板缺失

缺少啥[重复]

可可中缺少啥? [关闭]

我在这里缺少啥? IsSuccessStatusCode 无效