JavaScript深拷贝实现方法及引用问题解决技巧
JavaScript深拷贝是解决对象引用问题的关键技术,旨在创建与原对象完全隔离的副本,避免修改时相互干扰;本文系统剖析了四种主流实现方式——简洁但受限的JSON序列化、现代浏览器推荐的structuredClone()、灵活可控的手写递归方案,以及生产环境首选的Lodash _.cloneDeep(),并深入对比了它们在类型支持、循环引用处理、兼容性及适用场景上的核心差异,帮助开发者根据项目需求快速选择最合适的深拷贝策略。

JavaScript 中实现深拷贝的核心目标是创建一个与原对象完全独立的新对象,确保修改副本不会影响原始数据。引用问题(比如修改嵌套对象时意外改变原对象)通常源于浅拷贝或直接赋值,而深拷贝能彻底切断引用链。
JSON.parse(JSON.stringify()) —— 简单但有局限
这是最常用、写法最简洁的深拷贝方式,适合纯数据对象(只含字符串、数字、布尔值、null、数组、普通对象):
- ✅ 优点:一行代码搞定,性能尚可,兼容性好
- ❌ 缺点:会丢失函数、undefined、Symbol、Date、RegExp、Map、Set、BigInt 等类型;循环引用直接报错;不能处理原型链和不可枚举属性
- ⚠️ 示例:
const copy = JSON.parse(JSON.stringify(original));
structuredClone() —— 现代浏览器推荐方案
ES2022 引入的原生 API,支持更多数据类型,且能正确处理 Date、RegExp、Map、Set、ArrayBuffer、TypedArray 等:
- ✅ 优点:原生、安全、语义清晰、支持大部分结构化数据
- ❌ 缺点:目前不支持函数、undefined、Symbol、循环引用(仍会抛错),且在 Node.js 17+ 和较新浏览器中才可用
- ⚠️ 示例:
const copy = structuredClone(original);
递归手写深拷贝 —— 完全可控,适合复杂场景
当需要支持函数、自定义类型、循环引用或特殊逻辑时,需手动实现。关键点包括类型判断、递归遍历、缓存已拷贝对象(解决循环引用):
- 用
typeof和Object.prototype.toString.call()准确识别类型(如 Array、Date、RegExp、Map、Set) - 维护一个 WeakMap 记录源对象 → 拷贝对象的映射,遇到重复引用直接返回已有拷贝
- 对普通对象和数组递归处理每个键值;对特殊类型(如 Date)调用构造器新建实例
- ⚠️ 注意:不处理原型链上的属性,默认只拷贝自身可枚举属性(类似
Object.assign行为)
Lodash 的 _.cloneDeep() —— 生产环境稳妥选择
经过大量测试的成熟工具函数,覆盖绝大多数边界情况(包括函数、循环引用、稀疏数组、不可枚举属性等):
- ✅ 优点:健壮、文档完善、社区验证充分、支持自定义克隆逻辑(通过 customizer)
- ❌ 缺点:引入额外依赖,包体积增加;部分场景略重(如仅需简单拷贝)
- ⚠️ 使用:
import { cloneDeep } from 'lodash-es'; const copy = cloneDeep(original);
选择哪种方法取决于你的运行环境、数据结构复杂度和是否允许第三方依赖。日常开发中,优先考虑 structuredClone()(兼容性满足时),否则用 Lodash;临时调试或简单数据可用 JSON 方案;需要极致控制或学习原理,就动手写递归版本。
终于介绍完啦!小伙伴们,这篇关于《JavaScript深拷贝实现方法及引用问题解决技巧》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!
Win10关闭位置追踪方法教程
- 上一篇
- Win10关闭位置追踪方法教程
- 下一篇
- PS手绘板画直线技巧分享
-
- 文章 · 前端 | 3分钟前 |
- JavaScript代理对象是什么?如何用Proxy自定义对象操作?
- 273浏览 收藏
-
- 文章 · 前端 | 5分钟前 |
- CSS图标随文字颜色变化技巧
- 482浏览 收藏
-
- 文章 · 前端 | 5分钟前 |
- CSS制作带遮罩图片展示,绝对定位与透明度应用
- 361浏览 收藏
-
- 文章 · 前端 | 8分钟前 | HTML5
- HTML5用hr标签或CSS画直线分隔内容块
- 433浏览 收藏
-
- 文章 · 前端 | 14分钟前 |
- 反引号让JS多行文本更简洁易读
- 313浏览 收藏
-
- 文章 · 前端 | 14分钟前 |
- JavaScript WeakSet详解及使用场景
- 419浏览 收藏
-
- 文章 · 前端 | 17分钟前 |
- Hook规则是什么?Hook使用限制详解
- 390浏览 收藏
-
- 文章 · 前端 | 20分钟前 |
- Safari Gap兼容问题,媒体查询改用Margin解决
- 240浏览 收藏
-
- 文章 · 前端 | 23分钟前 |
- JavaScript 如何用 fetch 获取笑话数据
- 245浏览 收藏
-
- 文章 · 前端 | 28分钟前 |
- WebVitals库如何提升生产性能监控
- 204浏览 收藏
-
- 文章 · 前端 | 38分钟前 |
- Vue Slots在Markdown组件中的扩展应用
- 395浏览 收藏
-
MyBrand
- 文章 · 前端 | 41分钟前 | 常见HTML属性兼容性问题有哪些
- MyBrand
是的,translate 属性会影响 Google Translate 的自动翻译行为。1. translate="no"如果一个 HTML 元素或页面设置了 translate="no",Google Translate 会跳过该元素或整个页面,不进行翻译。适用于不需要翻译的内容,比如品牌名称、专有名词、代码片段等。示例:

