javascript浅拷贝处理数组时只复制第一层元素,基本类型值被真实复制,引用类型(如对象、嵌套数组)仅复制内存地址,新旧数组共享深层数据。

JavaScript 中浅拷贝处理数组时,只复制第一层元素,对内部的引用类型(如对象、嵌套数组)仍保留地址共享,修改深层内容会影响原数组。
浅拷贝只断开第一层引用
数组本身是引用类型,浅拷贝会创建一个新数组,但其中每个元素按值或地址分别处理:
- 基本类型元素(数字、字符串、布尔等)→ 真实复制一份值,互不影响
- 引用类型元素(对象、数组、日期等)→ 复制的是内存地址,新旧数组指向同一块堆内存
常见浅拷贝方法及其表现一致
无论用哪种方式,只要属于浅拷贝,对嵌套结构的处理逻辑完全相同:
-
展开运算符:
const newArr = [...oldArr] -
slice():
const newArr = oldArr.slice() -
concat():
const newArr = [].concat(oldArr) -
Array.from():
const newArr = Array.from(oldArr) - toReversed().reverse()(兼容性较弱,但也是浅拷贝)
例如:const arr = [1, {x: 2}]; const copy = [...arr]; copy[1].x = 99; → arr[1].x 也变成 99。
哪些情况看似“深”实为“浅”
容易误判的典型场景:
- 数组里全是基本类型(如
[1, 2, 3])→ 修改副本不会影响原数组,但这只是因为没出现引用类型,不代表方法是深拷贝 - 用
JSON.parse(JSON.stringify(arr))虽能隔离嵌套,但它不是浅拷贝,而是简易深拷贝,且有严重限制(丢函数、Symbol、undefined、循环引用报错) -
Object.assign([], arr)对数组也有效,但仍是浅拷贝,行为与slice()一致
为什么不能依赖浅拷贝做状态隔离
在 React、Vuex 或任何需要数据不可变性的场景中,浅拷贝不足以保证安全:
- 传入组件的数组 props 若含对象,组件内修改该对象属性,父组件状态意外变更
- 异步操作中基于原数组生成副本,后续对副本中对象的修改污染原始数据源
- 表单字段绑定嵌套对象时,浅拷贝后编辑会导致其他字段联动更新
真正需要独立副本时,必须明确判断是否含嵌套引用,并选择深拷贝方案或结构扁平化设计。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











