slice()和concat()是JavaScript中实现数组浅拷贝的两种经典方式,仅复制第一层元素,对嵌套对象或数组无效;二者均不修改原数组,但slice仅适用于Array实例,concat会尝试展开参数;现代更推荐扩展运算符[...arr]或Array.from()。

用 slice() 和 concat() 复制数组,是 JavaScript 中实现浅拷贝的两种经典方式,它们都只复制数组第一层元素,对嵌套对象或数组不起作用。
slice() 创建新数组
slice() 方法不修改原数组,返回一个从开始到结束(不包括结束位置)的浅拷贝。传入空参数(slice(0) 或 slice())可复制整个数组。
-
const newArr = arr.slice();最常用,简洁且语义清晰 -
slice()对类数组对象无效,仅适用于真正的 Array 实例 - 如果原数组含对象,新数组中该对象仍与原数组共享同一引用
concat() 拼接出副本
concat() 本意是合并数组,但传入单个数组时,会返回一个新数组,内容与原数组相同——这也是一种浅拷贝。
-
const newArr = arr.concat();空调用等价于复制自身 -
arr.concat([])或arr.concat(arr)也能得到副本,但没必要,直接用concat()即可 - 注意:
concat()会尝试展开参数,若传入对象(如{}),会被当作普通元素加入,不是拷贝行为
浅拷贝的局限性要清楚
两者都只拷贝数组顶层的值:数字、字符串、布尔值会被真正复制;而对象、数组、函数等引用类型,只是复制了指针,新旧数组中的对应项指向同一内存地址。
立即学习“Java免费学习笔记(深入)”;
- 例如:
const arr = [{a: 1}, [2]]; const copy = arr.slice(); copy[0].a = 99;→arr[0].a也会变成 99 - 需要深拷贝时,不能依赖
slice或concat,得用JSON.parse(JSON.stringify())(有局限)、结构化克隆(structuredClone)或第三方库
现代替代方案更推荐
虽然 slice 和 concat 仍可用,但现在更常用且语义更明确的方式是:
- 扩展运算符:
const newArr = [...arr]; Array.from(arr)- 三者效果一致,都是浅拷贝,但扩展运算符可读性最好,也支持类数组对象


















