javascript如何实现深拷贝_有哪些方法可以避免引用问题?
发布时间 - 2025-12-30 00:00:00 点击率:次JavaScript深拷贝需创建完全独立副本,避免引用问题;JSON方法简单但有类型限制;structuredClone是现代推荐方案;手写递归可定制但需处理循环引用等细节;Lodash的cloneDeep最全面可靠。
JavaScript 实现深拷贝的核心目标是:创建一个与原对象完全独立的新对象,所有嵌套的属性(包括对象、数组、日期、正则等)都重新分配内存,修改副本不会影响原始数据。引用问题本质上是浅拷贝导致的——只复制了引用地址,而非实际值。
JSON.parse(JSON.stringify()) —— 简单但有局限
这是最常用的一行式方案,适合纯数据对象(仅含字符串、数字、布尔、null、数组、普通对象):
const original = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(original));
⚠️ 注意限制:
- 会丢失函数、undefined、Symbol、BigInt、Date、RegExp、Map、Set、Promise 等类型(序列化时被忽略或转为 null)
- 无法处理循环引用,直接报错 TypeError: Converting circular structure to JSON
- Date 对象变成字符串,RegExp 变成空对象
structuredClone() —— 现代浏览器推荐方案
Chrome 98+、Firefox 94+、Edge 98+ 支持,能正确处理 Map、Set、Date、RegExp、ArrayBuffer、TypedArray、Error、Blob 等,并支持循环引用:
const original = { date: new Date(), regex: /abc/g, map: new Map([['key', 'value']]) };
const copy = structuredClone(original);
✅ 优点:原生、安全、语义清晰、性能较好
❌ 缺点:IE 不支持,部分 Node.js 版本(v17.0+
启用 --experimental-structured-cloning)才可用
手写递归深拷贝 —— 灵活可控,适合学习和定制
通过递归判断类型,分别处理基本类型、引用类型、特殊对象:
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
const clone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone;
}
? 关键点:
- 必须检查 null(typeof null === 'object' 是 JS 历史 bug)
- 用 Array.isArray() 判断数组,避免用 instanceof 在跨 iframe 场景失效
- 需单独处理 Date、RegExp、Map、Set 等,否则会退化为普通对象
- 要支持循环引用?需额外维护一个 WeakMap 记录已拷贝的对象对
使用成熟库 —— 快速可靠,减少重复造轮子
Lodash 的 _.cloneDeep() 是最广泛使用的方案:
import { cloneDeep } from 'lodash-es';
const copy = cloneDeep(original);
✅ 支持几乎所有 JS 内置类型、循环引用、自定义类实例(可配置)
✅ 经过大量生产环境验证,边界 case 处理完善
⚠️ 注意:体积略大(可按需引入),Tree-shaking 友好(用 lodash-es)
避免引用问题的本质,不是选哪个方法,而是明确你的数据结构和运行环境。简单 JSON 数据用 JSON 方法;现代浏览器项目优先 structuredClone;需要兼容老环境或高度定制就手写或用 Lodash。不复杂但容易忽略细节。
# javascript
# java
# js
# node.js
# json
# node
# 浏览器
# edge
# red
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法
零基础网站服务器架设实战:轻量应用与域名解析配置指南
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
深入理解Android中的xmlns:tools属性
实例解析angularjs的filter过滤器
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
如何登录建站主机?访问步骤全解析
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门
,交易猫的商品怎么发布到网站上去?
北京网站制作的公司有哪些,北京白云观官方网站?
javascript读取文本节点方法小结
深圳网站制作的公司有哪些,dido官方网站?
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
JavaScript如何实现类型判断_typeof和instanceof有什么区别
Laravel如何处理表单验证?(Requests代码示例)
WordPress 子目录安装中正确处理脚本路径的完整指南
深圳网站制作平台,深圳市做网站好的公司有哪些?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
Laravel如何使用Service Container和依赖注入?(代码示例)
iOS正则表达式验证手机号、邮箱、身份证号等
Laravel Session怎么存储_Laravel Session驱动配置详解
Laravel如何与Pusher实现实时通信?(WebSocket示例)
如何基于云服务器快速搭建个人网站?
jQuery validate插件功能与用法详解
Laravel如何实现数据库事务?(DB Facade示例)
如何在阿里云高效完成企业建站全流程?
Laravel storage目录权限问题_Laravel文件写入权限设置
如何注册花生壳免费域名并搭建个人网站?
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
Laravel如何创建自定义Artisan命令?(代码示例)
Laravel怎么实现验证码(Captcha)功能
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
如何快速辨别茅台真假?关键步骤解析
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
Laravel如何实现邮件验证激活账户_Laravel内置MustVerifyEmail接口配置【步骤】
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
javascript基于原型链的继承及call和apply函数用法分析
PythonWeb开发入门教程_Flask快速构建Web应用

