最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
JavaScript 中浅拷贝与深拷贝的本质区别与应用场景
时间:2026-07-01 11:19:51 编辑:袖梨 来源:一聚教程网
浅拷贝只复制第一层属性,嵌套引用类型仍共享内存;深拷贝递归复制所有层级,为每个嵌套对象开辟新内存空间。本质区别在于是否切断引用类型的内存共享关系,核心是一层复制 vs 全层独立。
浅拷贝与深拷贝的本质区别,在于是否切断引用类型的内存共享关系:浅拷贝只复制对象第一层属性,对嵌套的引用类型仍保留原地址;深拷贝则递归复制所有层级,为每个嵌套对象开辟全新内存空间。
核心差异:一层 vs 全层
JavaScript 中基本类型(如 number、string)赋值即拷贝值,互不影响;而引用类型(object、array 等)在内存中分两部分存储:栈中存地址,堆中存实际数据。拷贝行为的关键就落在这个“地址”是否被复用上:
- 浅拷贝:新对象的顶层属性值如果是基本类型,就复制值;如果是引用类型(比如一个子对象或数组),就复制那个地址——新旧对象仍指向堆中同一块数据
- 深拷贝:无论嵌套多深,遇到引用类型就新建堆内存、逐层复制内容,最终两个对象完全独立,修改互不干扰
常见浅拷贝方法及局限
这些方式都只处理第一层,适合结构扁平、无深层嵌套的场景:
-
展开运算符:
{...obj}或[...arr]——简洁常用,但对undefined、function、Date、RegExp等特殊对象会丢失或出错 -
Object.assign():
Object.assign({}, obj)——兼容性好,但同样不处理嵌套对象,且忽略不可枚举属性和原型链 -
数组方法:
arr.slice()、arr.concat()、[].concat(arr)——仅适用于数组,且对数组内含对象仍为浅拷贝
深拷贝的实现方式与取舍
没有银弹方案,需按需求选型:
立即学习“Java免费学习笔记(深入)”;
-
JSON 方法:
JSON.parse(JSON.stringify(obj))——最简,但会丢弃function、undefined、Symbol、Date、RegExp,且无法处理循环引用,仅适合纯数据对象(如 API 响应体) -
结构化克隆(现代推荐):
structuredClone(obj)(Chrome 98+、Node.js 17.0+ 支持)——原生、安全、支持多数内置类型(包括Date、Map、Set、ArrayBuffer),但暂不支持函数和自定义类实例 -
第三方库:Lodash 的
_.cloneDeep()功能全面,能处理函数、循环引用、特殊对象,但引入额外体积 -
手写递归:可控性强,可定制过滤逻辑(如跳过某些字段),但需谨慎处理循环引用、类型识别(
Array/Date/Map等)和性能问题
典型应用场景对比
什么时候该用哪种?关键看“改了副本,原数据能不能动”:
-
用浅拷贝:表单初始值快照(仅顶层字段)、UI 组件 props 透传(避免直接修改父级状态)、临时合并配置项(如
Object.assign(defaults, userConfig)) - 必须用深拷贝:编辑表单草稿时保存原始数据用于“取消”还原、Vuex/Pinia 中 state 初始化、测试中构造隔离数据、后端返回的数据需要本地持久化并频繁修改
-
注意陷阱:Vue/React 中直接修改 props 或响应式对象的嵌套属性,即使用了浅拷贝也可能触发视图更新异常;涉及
Date、Map等对象时,JSON方法会失效,应优先考虑structuredClone或库方案
相关文章
- 刀剑乱舞疲劳怎么办 疲劳度恢复攻略 07-01
- 不义联盟2史低价格是多少:不义联盟2历史最低价查询与购买建议 07-01
- 天堂2盟约骑士职业定位与进阶技巧天堂2盟约骑士玩法指南 07-01
- 采石场惊魂史低价攻略 采石场惊魂史最低价格查询与购买建议 07-01
- 息风谷战略仙竹海副本怎么玩 息风谷战略仙竹门副本通关技巧与阵容搭配 07-01
- 巴别塔圣歌史低价格是多少 巴别塔圣歌当前最低售价一览 07-01