为何JS的slice()方法文档称其为浅拷贝,测试却看似深拷贝?
澄清JavaScript中slice()的浅拷贝与深拷贝误解
嘿,我完全懂你为啥会有这个疑惑——刚测试的时候确实容易误以为slice()做了深拷贝,但其实问题出在你还没触及到浅拷贝的“边界”。咱们结合你的例子一步步拆解:
首先先把两个核心概念掰明白:
- 浅拷贝:只复制数组的顶层元素。如果顶层是数字、字符串这类基本类型,会复制它们的具体值;但如果顶层元素是嵌套数组、对象这类引用类型,复制的只是指向这个对象的引用地址——说白了,原数组和新数组里的嵌套元素其实是内存里同一个东西的“别名”。
- 深拷贝:会递归复制所有层级的元素,不管嵌套多少层,新数组的每一个元素(包括嵌套的)都是完全独立的新对象,改其中一个绝对不会影响另一个。
再看你的测试代码:
var array = [1,2,[3,4,[5,6]]]; var array2 = array.slice();
这时候打印两个数组,内容看起来完全一致,但这只是因为你还没去碰嵌套的数组部分。咱们加几行代码试试,马上就能看出差别:
// 修改原数组的顶层基本类型元素 array[0] = 100; console.log(array[0]); // 输出 100 console.log(array2[0]); // 输出 1(不受影响,因为顶层基本类型是值拷贝) // 现在修改原数组里的嵌套数组 array[2][0] = 300; console.log(array[2][0]); // 输出 300 console.log(array2[2][0]); // 也输出 300!(因为嵌套数组是引用拷贝,两者指向同一个内存对象)
看到了吧?这就是slice()作为浅拷贝的核心表现:顶层基本类型是独立的,但嵌套的引用类型还是共享的。你之前觉得像是深拷贝,只是因为没去修改嵌套部分而已。
如果真要实现深拷贝,你得用其他方法,比如自己写递归函数遍历复制每一层,或者用JSON.parse(JSON.stringify(array))(注意这个方法有局限性,没法处理函数、Symbol这类特殊值),也可以用第三方库的深拷贝工具。
内容的提问来源于stack exchange,提问作者zeckdude
相关产品推荐
相关产品推荐

