我对数组的理解缺少啥?
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);
c
和 a
引用不同的数组,但 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))
,这并不完美(你丢失了日期/正则表达式/其他“特殊”对象)。以上是关于我对数组的理解缺少啥?的主要内容,如果未能解决你的问题,请参考以下文章