前端深拷贝

news/2024/9/18 5:40:21/ 标签: 前端, javascript, 开发语言

什么是 structuredClone()?

structuredClone() 是 2022 年引入的全局函数,支持深度克隆 JavaScript 对象。与 JSON.stringify() 和 JSON.parse() 等传统方法不同,它们难以处理复杂的结构和循环引用,而 structuredClone() 可以毫不费力地处理这些挑战。

为什么它会改变游戏规则?

它是创建真正的深度克隆的强大工具,无需额外的逻辑或解决方法即可保持嵌套对象和循环引用的完整性。此外,它还可用于现代环境,包括 Web Workers。

1. 简单对象克隆:基础知识

  • 使用 {...obj} (浅拷贝)
javascript"> const original = { name: "Alice", details: { age: 25 } };const shallowCopy = { ...original };shallowCopy.details.age = 30;console.log(original.details.age); // 30console.log(shallowCopy.details.age); // 30

展开运算符 {...obj} 仅创建浅表副本。details 对象不是深度克隆的,因此对 shallowCopy.details 的更改也会影响原始详细信息

  • 使用 JSON.stringify() + JSON.parse()(深拷贝)
javascript">const original = { name: "Alice", details: { age: 25 } };
const deepCopy = JSON.parse(JSON.stringify(original));deepCopy.details.age = 30;console.log(original.details.age); // 25
console.log(deepCopy.details.age); // 30

此方法创建深层副本,但它有局限性:它无法处理函数、未定义或循环引用。

  • 使用 structuredClone()(深拷贝)
javascript">const original = { name: "Alice", details: { age: 25 } };
const clone = structuredClone(original);clone.details.age = 30;console.log(original.details.age); // 25
console.log(clone.details.age); // 30

structuredClone() 创建一个深度克隆,保留结构而不受 JSON.stringify() 的任何限制,并处理复杂的数据类型,如循环引用和 undefined

2. 处理循环引用:一项挑战

  • 带有 {...对象}
javascript">const original = { name: "Alice" };
original.self = original;// This will cause an error:
const shallowCopy = { ...original }; // TypeError: Converting circular structure to JSON

{...obj} 无法处理循环引用,从而导致错误。

  • 使用 JSON.stringify() 的循环引用
javascript">const original = { name: "Alice" };
original.self = original;// This will cause an error:
const jsonCopy = JSON.parse(JSON.stringify(original)); // TypeError: Converting circular structure to JSON

JSON.stringify() 也因循环引用而失败,从而引发错误。

  • 使用 structuredClone()  的循环引用
javascript">const original = { name: "Alice" };
original.self = original;const clone = structuredClone(original);console.log(clone !== original); // true
console.log(clone.self === clone); // true

structuredClone()  无缝处理循环引用,创建适当的深度克隆而不会出错。

3. 克隆 Functions 和 undefined:另一个测试

  • 使用 {...对象}
javascript">const original = { name: "Alice", greet: () => "Hello!", value: undefined };
const shallowCopy = { ...original };console.log(shallowCopy.greet()); // "Hello!"
console.log(shallowCopy.value); // undefined

{...obj} 按预期复制 functions 和 undefined,但只是浅层复制。

  • 使用 JSON.stringify()
javascript">const original = { name: "Alice", greet: () => "Hello!", value: undefined };
const jsonCopy = JSON.parse(JSON.stringify(original));console.log(jsonCopy.greet); // undefined
console.log(jsonCopy.value); // undefined

JSON.stringify() 无法序列化函数或 undefined,从而导致它们在克隆对象中丢失。

  • 使用 structuredClone()
javascript">const original = { name: "Alice", greet: () => "Hello!", value: undefined };
const clone = structuredClone(original);console.log(clone.greet); // undefined
console.log(clone.value); // undefined

structuredClone() 也不会克隆函数,但会保留未定义的值,因此对于复杂对象,它比 JSON.stringify()  更可靠。

4. 速度和效率:性能说明

大数据效率

javascript">const largeArray = new Array(1e6).fill({ key: "value" });// structuredClone: 161.200927734375 ms
console.time("structuredClone");
const clone = structuredClone(largeArray);
console.timeEnd("structuredClone");// JSON.stringify + JSON.parse: 690.014892578125 ms
console.time("JSON.stringify + JSON.parse");
const jsonCopy = JSON.parse(JSON.stringify(largeArray));
console.timeEnd("JSON.stringify + JSON.parse");

对于大型复杂数据,structuredClone() 通常比 JSON.stringify() + JSON.parse() 更快,并且避免了序列化和反序列化的陷阱。

5. 结论:为什么 structuredClone() 是未来

  • 可靠性:更可预测地处理循环引用、函数和未定义的值。
  • 效率:更快地对大型数据集执行深度克隆,并且不需要解决方法。
  • 简单性:一种方法可以统治所有 - 无需再在 {...obj}JSON.stringify() 或自定义深度克隆函数。


http://www.ppmy.cn/news/1525982.html

相关文章

C到C++入门基础知识

一:命名空间:namespace (一):命名空间的定义 注:命名空间只能定义在全局,不能定义在函数内部。 (1)类似于C语言的结构体,C语言的命名空间定义为&#xff1…

【React】React18.2.0核心源码解读

前言 本文使用 React18.2.0 的源码,如果想回退到某一版本执行git checkout tags/v18.2.0即可。如果打开源码发现js文件报ts类型错误请看本人另一篇文章:VsCode查看React源码全是类型报错如何解决。 阅读源码的过程: 下载源码 观察 package…

Docker 数据目录迁移:一篇详细的技术指南

在使用Docker进行容器化部署时,有时我们需要将Docker的数据目录(默认位于/var/lib/docker)迁移到新的位置。这可能是由于磁盘空间不足、存储优化或系统迁移等原因。本文将详细介绍如何将Docker数据目录迁移到新的目录下,包括所有必要的步骤和代码实现。 一、背景知识 Doc…

数据结构————二叉树基础知识(零基础包会的!)

今天带来数据结构二叉树的知识,保证大家不会离散数学或者没有数据结构基础,也能明明白白的。 一,树 1,树的结构 我们在了解什么是二叉树之前我们先了解下什么是树,树是一种非线性的数据结构,它是由n个节点…

Kafka 命令详解及使用示例

文章目录 Kafka 命令详解及使用示例Kafka 命令详解kafka-topics.sh:主题管理创建主题创建带副本的主题修改主题分区数了解分区分布列出主题查看主题详情删除主题 kafka-console-producer.sh:消息生产者发送消息到主题带键值对的消息消息生产性能优化带分…

node前端开发基本设置

加快下载源速度 要将 npm 切换到淘宝的源镜像,你可以按照以下步骤操作: 查看当前 npm 源: npm config get registry这个命令会显示当前使用的 npm 源地址,默认情况下它会是 https://registry.npmjs.org/。 切换到淘宝镜像&#…

基于SpringBoot的校园新闻网站设计与实现

需要项目源码请联系我,目前有各类成品 毕设 javaweb ssh ssm springboot等等项目框架,源码丰富。 专业团队,咨询就送开题报告,活动限时免费,有需要的朋友可以来留言咨询。 一、摘要 本论文主要论述了如何使用JAVA语言…

CISC 和 RISC 架构的对比

研究 RISC 架构优缺点的最简单方法是将其与其前身进行对比: CISC(复杂指令集计算机)架构。 内存中的两个数字相乘 右图表示一台普通计算机的存储方案。 主存储器被划分为编号从(行)1:(列&…

计算机组成原理(第二次笔记)

各种码 真值 (书写用): 将用“”、“-” 表示正负的二进制数称为真值 机器不能识别书写格式,故用“0/1”表示“/-”符号。 机器码 (机器内部使用): 将符号和数值一起编码表示的二进制数称为机器码。 常用机器码:原码、 反码、 补…

Centos 执行yum安装 出现Failed connect to mirrors.163.com:80; 拒绝连接

错误如下: http://mirrors.163.com/centos/7/os/x86_64/repodata/repomd.xml: [Errno 14] curl#7 - "Failed connect to mirrors.163.com:80; 拒绝连接 解决办法: 换镜像源地址 添加阿里的源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.al…

OCR 通用端到端模型GOT

摘要 在人工智能领域,光学字符识别(OCR)技术已经取得了显著的进展。随着技术的不断进步,我们正迈向OCR 2.0时代。本文将介绍由Vary团队开发的通用端到端模型GOT,这一模型在OCR领域具有革命性的潜力。 论文概览 论文…

一. rpc基本学习

1. 什么是rpc,为什么有了http还要rpc 我们常说的http,应该是说的http1,http只是应用层的一个协议 Rpc是一种调用方式,全称叫远程过程调用,对应本地调用,rpc是一种调用方式,不是一种协议 更具体…

Qt与MQTT交互通信

MQTT全称是(Message Queuing Telemetry Transport),即消息队列遥测传输协议 是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,并且该协议构建于TCP/IP协议之上,常用于互联网中&am…

【贪心算法】(二)贪心算法区间问题及进阶习题

贪心算法区间问题及进阶习题 贪心算法解决区间问题跳跃问题1. 跳跃游戏2. 跳跃游戏 Ⅱ 重叠区间问题3. 用最少数量的箭引爆气球4. 无重叠区间5. 划分字母区间6. 合并区间 其他问题7. 最大子序和8. 加油站9. 监控二叉树 贪心算法解决区间问题 跳跃问题 对于跳跃问题这一类问题&…

《OpenCV计算机视觉》—— 图像轮廓检测与绘制

文章目录 一、轮廓的检测二、轮廓的绘制图像轮廓检测与绘制的代码实现 三、轮廓的近似 一、轮廓的检测 轮廓检测是指在包含目标和背景的数字图像中,忽略背景和目标内部的纹理以及噪声干扰的影响,采用一定的技术和方法来实现目标轮廓提取的过程注意:做轮…

数据格式:什么是JSON和XML

JSON和XML都是数据交换的一种格式,用于在不同的系统和应用程序之间传输和存储数据。本文将解释JSON和XML的基础内容,并探讨两者的不同。 一 什么是JSON? 1. JSON(JavaScript Object Notation)即JavaScript对象标记法…

ThinkPHP Email功能如何配置才能发送邮件?

ThinkPHP Email发送流程?使用ThinkPHP发Email方法? ThinkPHP作为一款流行的PHP框架,提供了强大的Email功能,使得开发者能够轻松实现邮件发送。AokSend将详细介绍如何配置ThinkPHP Email功能,以确保邮件能够顺利发送。…

【Go】Go语言基本语法--注释、变量、常量

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

【C++】vector常见用法

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:C从小白到高手 🌹往期回顾🌹:[C]string类 🔖 流水不争,争的是滔滔不息。 文章目录 一、vector的介绍vector…

vite+vue3快速构建项目+router、vuex、scss安装

安装 Vite npm install -g create-vite-app创建vue3项目 npm init vitelatestnpm i安装依赖 安装veux、router npm install vue-router vuex新建router/index.js(自己创建home、login对应页面文件) import { createRouter, createWebHistory } from…