JS如何实现深拷贝_JavaScript深拷贝与浅拷贝区别及实现方法

深拷贝与浅拷贝的核心区别在于对引用类型处理方式不同:浅拷贝仅复制对象第一层属性,嵌套对象仍共享引用,修改会相互影响;深拷贝则递归复制所有层级,生成完全独立的新对象。常见浅拷贝方法包括Object.assign、扩展运算符、slice/concat等,但均只复制引用地址;JSON.parse(JSON.stringify(obj))可实现深拷贝,但无法处理函数、undefined、Symbol、循环引用及Date类型;手写递归深拷贝通过WeakMap解决循环引用问题,支持Date、RegExp等特殊类型,兼容性好;structuredClone为现代浏览器提供的原生深拷贝API,功能强大且支持复杂类型和循环引用,但兼容性有限。实际应用中需根据数据结构复杂度、特殊类型存在与否及浏览器兼容需求选择合适方案,手写递归通常是最稳妥选择。

js如何实现深拷贝_javascript深拷贝与浅拷贝区别及实现方法

JavaScript中的深拷贝和浅拷贝主要区别在于对引用类型数据的处理方式。当你复制一个对象时,如果该对象包含嵌套的对象或数组,浅拷贝只会复制第一层属性,而更深层的引用仍然指向原对象;深拷贝则会递归复制所有层级,生成一个完全独立的新对象。

浅拷贝 vs 深拷贝的区别

浅拷贝:只复制对象的第一层属性。对于基本类型值,复制的是值本身;对于引用类型(如对象、数组),复制的是引用地址,因此新旧对象共享嵌套结构,修改会影响彼此。

深拷贝:递归复制对象的所有层级,包括嵌套的对象和数组,生成一个全新的、与原对象无任何关联的独立副本。修改新对象不会影响原对象。

常见浅拷贝方法:Object.assign({}, obj) {…obj} Array.prototype.slice() / concat()注意:这些方法都只能实现浅拷贝。

JSON.stringify + JSON.parse 实现深拷贝

这是最简单的深拷贝方法之一:

立即学习“Java免费学习笔记(深入)”;

const deepCopy = JSON.parse(JSON.stringify(originalObj));

优点:语法简单,能处理大多数普通对象和数组的深拷贝。

缺点:有明显局限性:

无法处理函数、undefined、Symbol等非可序列化类型 会忽略 Symbol 属性键 不能处理循环引用(会报错) Date 对象会被转为字符串

因此,仅适用于纯数据对象(POJO)且不含特殊类型的场景。

手写递归实现深拷贝

为了克服 JSON 方法的限制,可以手动编写递归函数实现更完整的深拷贝:

function deepClone(obj, hash = new WeakMap()) {
if (obj == null) return obj;
if (typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
// 防止循环引用
if (hash.has(obj)) return hash.get(obj);
// 保留构造函数信息
const clone = new obj.constructor();
hash.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}

这个版本支持 Date、RegExp,并使用 WeakMap 解决循环引用问题,兼容性较好。

使用 structuredClone(现代浏览器)

现代浏览器提供了原生的深拷贝 API:

const deepCopy = structuredClone(originalObj);

它支持很多复杂类型,包括 transferable objects,也支持循环引用。但兼容性有限(Chrome 98+ 等较新版本支持),不适合需要兼容老浏览器的项目。

基本上就这些常见的实现方式。选择哪种方法取决于你的具体需求:数据结构是否复杂、是否包含特殊类型、是否需要兼容老浏览器等。多数情况下,手写递归加 WeakMap 是比较稳妥的选择。

以上就是JS如何实现深拷贝_JavaScript深拷贝与浅拷贝区别及实现方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1536551.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
动态网格重绘中的DOM管理与优化实践
上一篇 2025年12月21日 03:22:52
Google表单自动化提交:利用编程实现动态数据填充
下一篇 2025年12月21日 03:23:00

相关推荐

  • 浏览器JavaScript设置_网页脚本控制方法

    调整浏览器javascript设置可提升安全性和隐私保护,防止恶意脚本攻击;2. 有助于优化网页加载速度和性能,避免低效脚本拖慢浏览体验;3. 可用于排查网页显示异常或功能故障,判断是否由javascript冲突引起;4. 全局禁用javascript会导致绝大多数现代网站功能失效,影响正常使用;5…

    2026年8月31日
    000
  • 快手极速版和快手有什么区别_快手极速版与快手对比

    快手和快手极速版不是同一平台,前者功能全适合创作与直播带货,后者更轻便专注刷视频赚金币,广告多但支持拉新变现。 如果您在选择使用快手还是快手极速版时感到困惑,可能是因为两者在功能、收益模式和用户体验上存在显著差异。了解这些区别有助于您根据自身需求做出合适的选择。 本文运行环境:华为Mate 60 P…

    2026年8月31日
    100
  • 谷歌加速器游戏版费用说明_免费使用条件与功能介绍

    付费加速器提供更优线路与稳定连接,免费版多有限制且存安全风险,建议根据需求选择正规渠道产品并关注用户评价与隐私政策。 加速器游戏版,一般来说,分为免费和付费两种模式。免费版通常会有一些限制,比如线路选择较少、加速效果一般、广告较多等等。而付费版则能提供更优质的加速体验,更好的线路、更稳定的连接,以及…

    2026年8月31日
    500
  • 使用minio搭建私有化对象存储服务

    使用minio搭建私有化对象存储服务使用minio搭建私有化对象存储服务使用minio搭建私有化对象存储服务使用minio搭建私有化对象存储服务

    在工作中,我们常常会接触到对象存储服务,但这些服务大多是云服务。对于需要对外开放的项目而言,这类服务是可行的。然而,当我们需要私有化部署时,如何继续使用对象存储呢? 这里介绍一个开源项目MinIO,使用它,我们可以轻松搭建属于自己的私有云服务。 MinIO是一个非常轻量级的服务,可以简单地与其他应用…

    2026年8月31日 用户投稿
    000
  • 手机国补在哪里申请?附2025最新申请入口

    关于手机国补,需要明确的是,这通常并非一项全国统一、直接发放现金的补贴政策。在大多数情况下,“国补”是多种形式惠民措施的统称,可能体现为地方政府为提振消费而推出的消费券或专项补贴、通信运营商为推广5G套餐而提供的购机优惠,或是大型电商平台联合品牌方举办的以旧换新活动。这些政策具有很强的地域性和时效性…

    2026年8月31日
    000
  • Element Plus弹框内Three.js渲染出现空白区域,如何解决?

    Element Plus弹框中集成Three.js渲染3D场景时,底部出现空白区域,这并非Three.js渲染问题,而是CSS样式冲突导致。文章标题为“Element Plus和Three.js构建3D预览窗口,出现底部空白区域”,核心问题是Three.js渲染容器(#container)未能完全填…

    2026年8月31日
    000
  • 通过 Eloquent 模型关联实现订单菜品分组

    本文旨在介绍如何使用 Laravel Eloquent 模型关联,根据餐厅 ID 获取订单信息,并将订单中的菜品按照订单 ID 进行分组,最终返回包含订单详细信息和菜品列表的 JSON 数据。通过 `with()` 和 `whereHas()` 方法,可以避免使用循环,提高查询效率,使代码更加简洁易…

    2026年8月31日
    100
  • Element Plus与Three.js结合使用时,3D预览窗口出现空白区域该如何解决?

    Element Plus和Three.js结合使用:3D预览窗口空白区域问题排查与解决 在使用Element Plus和Three.js构建3D预览窗口时,可能会遇到意想不到的空白区域问题(如下图所示)。本文将分析此问题,并提供解决方案。 问题描述: 使用Element Plus的el-dialog…

    2026年8月31日
    000
  • 小米路由器192.168.31.1.miwifi.com网络管理

    首先确认设备已连接小米路由器wi-fi,其次检查浏览器地址输入是否正确,接着尝试重启路由器,若仍无法访问可尝试重置路由器并重新配置,同时可清除浏览器缓存、更换浏览器、检查防火墙设置、使用手机app管理、排查ip地址冲突;若问题持续,建议升级固件或联系售后。1. 确认设备连接正确网络;2. 核对并正确…

    2026年8月31日
    300
  • 如何在Java中配置CLASSPATH环境变量

    CLASSPATH是Java中用于指定类和资源文件路径的环境变量或参数,JVM和编译器依赖它查找.class文件及jar包。其路径列表在Windows用分号、Linux/macOS用冒号分隔,可包含目录、jar或zip文件。未正确设置会导致“找不到类”或NoClassDefFoundError错误。…

    2026年8月31日
    000
  • kk在线播放免费高清视频播放器入口 kk高清播放器网页版地址

    在寻找流畅便捷的高清在线视频服务时,了解不同平台的特点与风险至关重要。本文旨在帮助您辨别和选择优质、安全的在线播放平台,确保获得稳定可靠的观看体验,并有效规避潜在的网络安全问题。 一、了解在线高清播放平台 1、当用户寻找类似“kk高清播放器”的网页版入口时,其核心诉求是能够方便快捷地在线观看高清画质…

    2026年8月31日
    000
  • HBase列式存储究竟是如何工作的?它与传统行式数据库有何区别?

    HBase:深入理解其高效的列式存储 hbase,作为一款基于hadoop的分布式nosql数据库,其独特的列式存储机制使其在处理海量数据时展现出显著优势,与传统的行式数据库(如mysql)有着本质区别。本文将阐述hbase列式存储的原理,并揭示其高效性的关键所在。 HBase的核心概念是“列族”(…

    2026年8月31日
    100
  • 如何将JavaScript可选链操作符转换为ES5兼容代码?

    将现代JavaScript可选链操作符代码转换为ES5兼容代码 许多现代JavaScript代码利用可选链操作符(?.)安全地访问嵌套对象的属性,防止因属性缺失导致错误。例如:const name = data?.name; 这种简洁的语法在旧版浏览器或环境中可能无效,因为它依赖于ES2020及以上…

    2026年8月31日
    000
  • 迅雷浏览器怎么更换皮肤_迅雷浏览器主题设置教学

    可通过内置主题库或本地导入更换迅雷浏览器皮肤,支持自定义风格与恢复默认设置。 如果您希望个性化您的迅雷浏览器界面,使其更符合个人审美或使用习惯,可以通过更换皮肤来实现。迅雷浏览器支持多种主题样式,以下为具体设置方法: 一、通过内置主题库更换皮肤 迅雷浏览器自带主题中心,用户可直接在浏览器设置中浏览并…

    2026年8月31日
    100
  • IOS,安卓,Windows和塞班,你最喜欢哪个?为什么?

    IOS,安卓,Windows和塞班,你最喜欢哪个?为什么?IOS,安卓,Windows和塞班,你最喜欢哪个?为什么?IOS,安卓,Windows和塞班,你最喜欢哪个?为什么?IOS,安卓,Windows和塞班,你最喜欢哪个?为什么?

    从事软件开发多年,我主要使用c++/c++和java进行开发,涉及ios、android、windows和塞班四个系统的开发。除了ios系统外,其余三个系统我都有深入的开发经验。其中,我在android系统上花费的时间最长,研究过其中间层的framework框架,并从事过两年的应用级开发。从技术角度…

    2026年8月31日 用户投稿
    000
  • JavaScript异步函数中如何避免`response.rows[0] is undefined`错误?

    在javascript异步函数中如何避免undefined错误? 在使用异步函数处理数据时,经常会遇到由于数据未返回或返回的数据结构不符合预期而导致的错误。本文将针对一个实际案例,分析如何避免response.rows[0] is undefined这类错误。 问题代码片段如下: getplat({…

    用户投稿 2026年8月31日
    000
  • 谷歌浏览器如何将手机书签同步到电脑端?

    要将谷歌浏览器手机端的书签同步到电脑端,核心在于利用谷歌的同步功能。本文将详细为您介绍如何通过在手机和电脑两端登录同一个谷歌账户,并正确配置同步选项,来实现书签的无缝衔接。整个过程操作简单,遵循以下步骤即可轻松完成设置,让您在不同设备间自由访问收藏的网页。 立即进入“高清国产电影网站合集☜☜☜☜☜点…

    2026年8月31日
    000
  • VSCode怎么写JS代码_VSCode编写和调试JavaScript代码的完整教程

    答案是掌握配置环境、善用编辑器功能与调试技巧。首先安装Node.js并配置VSCode的launch.json文件以支持调试,安装ESLint和Prettier等插件提升代码质量;利用代码片段、智能提示和快捷键提高编写效率;通过设置断点、使用条件断点和调用堆栈等功能进行高效调试,遇到问题可检查配置、…

    2026年8月31日
    000
  • MySQL的InnoDB和MyISAM引擎区别是什么_该如何选择?

    MySQL的InnoDB和MyISAM引擎区别是什么_该如何选择?MySQL的InnoDB和MyISAM引擎区别是什么_该如何选择?MySQL的InnoDB和MyISAM引擎区别是什么_该如何选择?MySQL的InnoDB和MyISAM引擎区别是什么_该如何选择?

    innodb与myisam的核心差异在于事务支持、并发控制和数据完整性。1.innodb支持事务(acid特性)、行级锁定、外键约束和崩溃恢复,适合高并发、数据一致性要求高的场景;2.myisam采用表级锁定、无事务支持、无外键约束,仅在极少数读多写少、数据一致性要求低的场景下可能被考虑;3.inn…

    2026年8月31日 用户投稿
    000
  • 怎样备份谷歌浏览器收藏的书签?

    为防止因设备更换、系统重装或意外情况导致收藏的网页丢失,备份谷歌浏览器的书签是一项非常重要的操作。本文将为您详细介绍两种主流且有效的书签备份方法:一种是利用谷歌账户进行云端自动同步备份,另一种是手动将书签导出为本地文件进行备份。通过学习以下步骤,您可以选择最适合自己的方式,为您的宝贵书签数据提供双重…

    2026年8月31日
    100

发表回复

登录后才能评论
关注微信