新闻中心
J*aScript实现深拷贝的几种方案对比_js编程实践
深拷贝需根据场景选择方法:JSON方法简洁但不支持函数、循环引用等;手动递归可定制但复杂;结构化克隆支持多数内置对象但异步;Lodash最稳定但增加依赖。

深拷贝在J*aScript中是一个常见但容易出错的操作。它指的是创建一个新对象,其属性和嵌套对象的值都与原对象完全独立。修改新对象不会影响原始对象。实现深拷贝有多种方式,每种都有其适用场景和局限性。下面介绍几种主流方法,并进行对比分析。
1. JSON.parse(JSON.stringify())
这是最简单、最常用的深拷贝方法之一。
优点:- 语法简洁,一行代码即可完成。
- 能处理常见的数据类型:对象、数组、字符串、数字、布尔值等。
- 无法处理函数、undefined、Symbol,这些值会被忽略。
- 不能复制循环引用,会报错。
- Date对象会被转换为字符串。
- Map、Set、RegExp等特殊对象无法正确复制。
- 原型链上的属性不会被保留。
适合场景:仅用于纯数据对象(POJO),且不包含复杂类型或循环引用的情况。
2. 手动递归实现深拷贝
通过递归遍历对象属性,逐层复制。
示例代码:
function deepClone(obj, seen = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (seen.has(obj)) return seen.get(obj); // 处理循环引用
<p>let clone;
if (obj instanceof Date) {
clone = new Date(obj);
} else if (obj instanceof RegExp) {
clone = new RegExp(obj);
} else if (Array.isArray(obj)) {
clone = obj.map(item => deepClone(item, seen));
} else {
clone = {};
seen.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], seen);
}
}
}
return clone;
}</p>优点:- 可自定义处理各种数据类型。
- 支持循环引用(使用WeakMap)。
- 灵活性高,可根据需求扩展。
- 代码量较大,需要考虑多种边界情况。
- 手动维护类型判断逻辑,容易遗漏。
适合场景:需要精确控制拷贝行为,或处理复杂对象结构时。
3. 使用结构化克隆算法(Structured Clone)
HTML5提供的结构化克隆算法可用于深拷贝,可通过MessageChannel或postMessage间接使用。
示例:
function structuredClone(obj) {
return new Promise(resolve => {
const { port1, port2 } = new MessageChannel();
port2.onmessage = e => resolve(e.data);
port1.postMessage(obj);
});
}
// 注意:需异步调用
structuredClone(obj).then(clone => { /* 使用clone */ });
优点:- 浏览器原生支持,性能较好。
- 支持多数内置对象(Date、RegExp、Map、Set、Blob等)。
- 自动处理循环引用。
- 不支持函数和undefined。
- 必须异步调用,使用不便。
- 某些类型仍受限(如Error对象、DOM节点)。
适合场景:在现代浏览器中处理复杂数据结构,且可以接受异步操作。
Visla
AI视频生成器,快速轻松地将您的想法转化为视觉上令人惊叹的视频。
100
查看详情
4. 利用第三方库(如 Lodash)
Lodash 提供了 _.cloneDeep 方法,功能完善且经过充分测试。
示例:
const _ = require('lodash');
const cloned = _.cloneDeep(obj);
优点:- 稳定可靠,覆盖大多数边缘情况。
- 支持大量J*aScript类型(包括Map、Set、Date、RegExp等)。
- 处理循环引用无压力。
- 引入额外依赖,增加包体积。
- 对于简单项目可能“杀鸡用牛刀”。
适合场景:项目已使用Lodash,或对深拷贝稳定性要求极高。
总结对比
不同方案各有侧重:
- JSON方法最轻便,但限制多,仅适用于简单数据。
- 手动递归灵活可控,适合定制化需求。
- 结构化克隆接近原生,但异步使用略麻烦。
- Lodash等库最稳健,推荐在生产环境使用。
选择哪种
方式,取决于你的具体需求:是否涉及复杂类型、是否有循环引用、是否允许异步、是否已有工具库等。
基本上就这些。理解每种方法的边界,才能在实际开发中做出合理选择。
以上就是J*aScript实现深拷贝的几种方案对比_js编程实践的详细内容,更多请关注其它相关文章!
# 是一个
# seo关键词怎么裂变
# 东莞整合网站建设推广
# 永州软文营销推广
# 雅安网站建设推广哪家好
# 情感网站建设
# 长沙营销推广报价
# 广告推广加盟网站
# 合肥网站推广选哪家好些
# 海外营销推广证书考试时间
# 乐山营销推广免费咨询电话
# 它很
# 如何防止
# 您的
# 这是
# javascript
# 有什么区别
# 结构化
# 数据结构
# 几种
# 递归
# red
# 工具
# 浏览器
# html5
# json
# js
# html
# java
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
C#使用XPath查询节点时出错? 常见语法错误与调试技巧
C++如何操作注册表_Windows平台下C++读写注册表的API函数详解
解决 MongoDB 聚合查询中对象数组 _id 匹配问题
jQuery Mask 插件中实现电话号码固定前导零的教程
限制HTML日期输入框的日期选择范围
QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口
qq游戏手机版下载安装_qq游戏移动端入口
c++ 获取系统当前时间 c++时间戳获取方法
荣耀Play7T运行卡顿解决_荣耀Play7T性能优化
Python实时数据流中的动态最值查找策略
QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用
在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析
深入理解J*a链表中的IPosition接口与使用
Win10如何恢复误删的快捷方式_Win10重建常用软件快捷方式
ArrayList与LinkedList操作复杂度详解:遍历与修改
c++ 命名空间怎么用 c++ namespace使用指南
免费抖音短视频入口_抖音网页版短视频免费通道
百度浏览器字体显示异常偏小_百度浏览器字体渲染修复方案
uc浏览器网页版入口 uc浏览器网页版最新网址
最新韩小圈网页版登录入口_官网在线观看官方链接
ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句
《噬血代码2》新预告片发布 展示游戏剧情
小红书网页版入口链接分享 小红书官网直接进
深入理解Google Cloud Datastore查询:祖先路径与数据一致性
React Router v6 教程:构建认证保护的私有路由与重定向策略
包子漫画官方网站在线链接-包子漫画在线阅读平台主页地址
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
曝R星经典之作开发图 设计简陋但信息密集!
Mudbox图层蒙版怎么用_Mudbox图层蒙版数字雕刻应用技巧
零跑汽车11月交付量达70327台 实现连续9个月正增长
NRF24L01数据传输深度解析:解决大载荷接收异常与分包策略
知音漫客官网漫画下载_知音漫客网页版阅读记录
格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施
Go语言HTML解析:利用Goquery精准获取指定元素内容
Win11怎么关闭快速启动_Win11彻底关机设置教程
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
UC浏览器网页版登录入口官网 电脑版网址入口
解决 Express.js 中 PUT 请求密码修改失败的路由配置指南
Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议
夸克浏览器图书入口 夸克手机浏览器阅读入口
163邮箱注册官网 免费申请163个人邮箱
LocoySpider如何部署到云服务器_LocoySpider云部署的远程配置
漫蛙2正版漫画站 漫蛙2网页版快速访问入口
XML中包含HTML标签导致解析错误? 正确嵌入非XML数据的两种方法
poki网页游戏推荐_poki免费游戏平台入口
在J*a中如何开发简易博客标签推荐系统_博客标签推荐项目实战解析
poki免费入口快捷访问 poki人气小游戏直接玩站点
在J*a中如何开发简易仓库管理与库存统计_仓库管理库存统计项目实战解析
c++如何实现单例设计模式_c++线程安全的单例模式写法
Composer的 "licenses" 命令如何帮助你遵守开源协议_检查项目依赖的许可证合规性


2025-11-16
浏览次数:次
返回列表