slice()和concat()实现数组浅拷贝,本质是返回新数组但仅复制第一层引用,嵌套对象仍共享内存地址,修改其属性会同步影响原数组。

JavaScript 中用 slice() 和 concat() 实现数组浅拷贝,本质是利用它们不修改原数组、返回新数组的特性。这两种方法都只复制第一层引用,对嵌套对象或数组无效——即“浅拷贝”。
用 slice() 创建浅拷贝
slice() 从原数组截取一段并返回新数组。传入空参数(slice(0) 或 slice())就能复制整个数组。
-
arr.slice()或arr.slice(0)效果相同,都返回一个新数组,内容与原数组一致 - 原数组不受影响,包括 length、元素顺序、引用关系都保持不变
- 若原数组含对象或子数组,新数组中对应位置仍是同一引用,修改嵌套内容会影响两边
示例:
const original = [1, 2, {name: 'Alice'}];const copy = original.slice();
copy[0] = 99; // 只影响 copy
copy[2].name = 'Bob'; // original[2].name 也会变成 'Bob'
用 concat() 创建浅拷贝
concat() 用于合并数组,但传入单个数组时(如 arr.concat() 或 arr.concat([])),它会返回该数组的副本。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
arr.concat()是最简写法,等价于arr.concat([]) - 和
slice()一样,只拷贝第一层,嵌套值仍共享引用 - 注意:不能传入原始值如
arr.concat(null),否则会把null当作元素加入新数组
示例:
const original = ['a', ['x', 'y']];const copy = original.concat();
copy.push('z'); // original 不变
copy[1].push('z'); // original[1] 也变成 ['x', 'y', 'z']
什么时候选 slice 还是 concat
两者在浅拷贝场景下效果一致,差异在于语义和习惯:
- 侧重“提取副本”,用
slice()更直观;它是专为截取设计的方法 - 侧重“组合前先备份”,或已有拼接逻辑,用
concat()更自然 - 性能上无明显差别,现代引擎优化良好,可按可读性选择
浅拷贝的局限与提醒
slice 和 concat 都不解决嵌套结构的拷贝问题。如果需要完全独立的副本(深拷贝),应考虑 structuredClone()(现代环境)、JSON.parse(JSON.stringify())(简单数据)、或第三方库如 Lodash 的 cloneDeep()。
另外,扩展运算符 [...arr] 也是常用浅拷贝方式,行为与 slice() 基本一致,且更简洁易读。

















