You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:46:26