JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的区别
JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的异同点
一、什么是 structuredClone?
1. structuredClone 的发展
structuredClone
是在 ECMAScript
2021(ES12)标准中引入的,ECMAScript
2021 规范正式发布于 2021 年 6 月
自 2022 年 3 月起,该功能适用于最新的设备和浏览器版本
Baseline 2022 Newly available
Since March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
2. structuredClone 的功能
2.1. 功能
全局的 structuredClone()
方法使用结构化克隆算法将给定的值进行深拷贝
2.2. 语法
structuredClone(value)
structuredClone(value, { transfer })
2.2. 参数
- value:被克隆的对象
- transfer:可转移的数组
2.3. 返回值
返回值是原始值的深拷贝
2.4.
如果输入值的任一部分不可序列化,则抛出 DataCloneError
异常
3. 用法
3.1. 普通用法
const obj = {
name: '日升',
sex: '男',
blog: {
csdn: 'https://guoqiankun.blog.csdn.net/?type=blog',
jj: 'https://juejin.cn/user/2409752520033768/posts'
},
games: ['cf', '黑马喽', 'cs'],
age: 18,
bool: true,
set: new Set([1,2,3]),
map: new Map([['a', 'b'], ['c', 'd']]),
null: null,
und: undefined
}
const cloneObj = structuredClone(obj);
3.2. transfer 用法
transfer
是一个可转移对象的数组,里面的值并没有被克隆,而是被转移到被拷贝对象上
const buffer = new ArrayBuffer(16);
console.log('buffer', buffer);
const cloned = structuredClone(buffer, { transfer: [buffer] });
console.log('buffer', buffer);
console.log('cloned', cloned);
二、structuredClone 和 JSON.parse(JSON.stringify()) 的区别
1. 支持的数据类型
从上面的示例中能看出,structuredClone
支持了很多中数据类型,基本类型和普通对象都支持
1.1. structuredClone
1.1.1. 支持的类型
- 基本类型
- 普通对象
Date
对象RegExp
对象Map
Set
ArrayBuffer
TypedArrays
Blob
File
ImageData
MessagePort
null、undefined
NaN、Infinity、
-Infinity- 循环引用
1.1.2. 不支持的类型
- 函数
symbol
WeakMap
WeakSet
HTMLElement
1.1.3. 示例
const port1 = new MessageChannel().port1
const obj = {
date: new Date(),
regex: /test/i,
map: new Map([['key1', 'value1'], ['key2', 'value2']]),
set: new Set([1, 2, 3]),
arrayBuffer: new ArrayBuffer(8),
typedArray: new Uint8Array([1, 2, 3]),
blob: new Blob(['Hello, world!'], { type: 'text/plain' }),
file: new File(['file content'], 'filename.txt', { type: 'text/plain' }),
imageData: (() => {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
return context.createImageData(100, 100);
})(),
messagePort: port1,
nullValue: null,
undefinedValue: undefined,
nanValue: NaN,
infinityValue: Infinity,
negativeInfinityValue: -Infinity,
circularRef: {}
};
// 创建循环引用
obj.circularRef.self = obj;
// 克隆 obj 对象
const clonedObj = structuredClone(obj, {transfer: [port1]});
// 输出以验证
console.log(clonedObj);
const obj = {
func: function() { return "I'm a function"; }, // 函数
symbol: Symbol('uniqueSymbol'), // Symbol
weakMap: new WeakMap(), // WeakMap
weakSet: new WeakSet(), // WeakSet
element: document.createElement('div') // HTMLElement
};
// 尝试克隆对象
try {
const clonedObj = structuredClone(obj);
console.log(clonedObj); // This line won't run if an error is thrown
} catch (error) {
console.error('Error:', error); // DataCloneError: Failed to execute 'structuredClone'
}
1.2. JSON.parse(JSON.stringify())
1.2.1. 支持的类型
- 数字
- 字符串
- 布尔值
- 数组
- 普通对象
1.2.2. 不支持的类型
- Date、Map、Set、RegExp、Function、undefined、symbol、Infinity、NaN、循环引用...
JSON.stringify 详细信息可以看下下面的文章
1.2.3. 示例
JSON.parse(JSON.stringify({
a: null,
b: undefined,
c: NaN,
d: Infinity,
e: () => ({}),
f: new Map(),
g: new Set(),
h: Symbol('a'),
i: Infinity
}))
// 返回值
{
"a": null,
"c": null,
"d": null,
"f": {},
"g": {},
"i": null
}
2. 循环引用
2.1. structuredClone
可以正确处理对象中的循环引用
2.2. JSON.parse(JSON.stringify)
如果对象中存在循环引用,调用 JSON.stringify 会抛出错误,导致克隆失败
3. 性能方面
3.1. structuredClone
通常在处理复杂对象时性能更优,特别是包含大量非 JSON 兼容类型的数据时,因为它是为深度克隆设计的原生方法,内部优化了许多复杂场景
3.2. JSON.parse(JSON.stringify)
在处理简单的、JSON 兼容的数据结构时可能性能较好,但在处理复杂对象或非 JSON 兼容类型时效率低下
4. 浏览器兼容
4.1. structuredClone
是一种较新的 API
,在某些较旧的浏览器中不被支持
4.2. JSON.parse(JSON.stringify)
在现代浏览器和较旧的浏览器中都有广泛支持
三、总结
structuredClone
提供了更广泛的数据类型支持和对循环引用的处理能力,适用于复杂场景JSON.parse(JSON.stringify)
适合处理简单、JSON
兼容的数据结构,但在处理复杂数据类型或循环引用时有局限性- 两者都有限制,克隆的时候需要关注下克隆对象的数据类型再做选择
参考
JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的区别的更多相关文章
- javascript 数组和对象的浅复制和深度复制 assign/slice/concat/JSON.parse(JSON.stringify())
javascript 数组和对象的浅度复制和深度复制在平常我们用 ‘=’来用一个变量引用一个数组或对象,这里是‘引用’而不是复制下面我们看一个例子引用和复制是什么概念 var arr=[1,2,3,' ...
- 关于JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑
JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反 ...
- 实现深拷贝还在用JSON.parse(JSON.stringify(obj))?带你用JS实现一个完整版深拷贝函数
使用JavaScript实现深拷贝 1.JSON序列化实现深拷贝 在JS中,想要对某一个对象(引用类型)进行一次简单的深拷贝,可以使用JSON提供给我们的两个方法. JSON.stringfy():可 ...
- JSON.parse JSON.stringify
JSON.stringify() undefined 值.函数或者XML值会被忽略 数组当中含有 undefined值,函数或XML值,该数组中的这些值将会被当成 null 正则对象会被转成空对象 J ...
- JSON.parse(JSON.stringify()) 实现对对象的深拷贝
JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反 ...
- JSON.parse() JSON.stringify() eval() jQuery.parseJSON() 的区别
http://www.jb51.net/article/81880.htm : jQuery.parseJSON(jsonString) : 将格式完好的JSON字符串转为与之对应的Java ...
- 使用JSON.parse(),JSON.stringify()实现对对象的深拷贝
根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系. 测试例子: var test={ a:"ss", ...
- JSON.parse(JSON.stringify(obj))
JSON.parse(JSON.stringify(obj)实现数组的深拷贝 利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象
- 【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较
样本:1MB的JSON文件,引入后生成500份的一个数组: 结果如下: 拷贝性能: JSON.parse(JSON.stringify()) 的方法:2523.55517578125ms immuta ...
- this.treeData = JSON.parse(JSON.stringify(this.d)) 树的序列化反序列化
this.treeData = JSON.parse(JSON.stringify(this.d))
随机推荐
- Flask API 如何接入 i18n 实现国际化多语言
1. 介绍 上一篇文章分享了 Vue3 如何如何接入 i18n 实现国际化多语言,这里继续和大家分享 Flask 后端如何接入 i18n 实现国际化多语言. 用户请求 API 的多语言化其实有两种 ...
- ArchSummit回顾:从云原生到实时数据湖,架构如何支撑业务发展
[点击了解更多网易热点] 数字化.自动化.智能化的主旋律下,架构的进化也在提速.在近日举办的ArchSummit全球架构师峰会上,网易数帆高级技术专家.资深架构师裴斐和网易数帆高级技术专家周劲松分别分 ...
- Windows11下使用VcXsrv+xfce4实现图形化窗口
通过 sudo apt-get install xfce4-terminal sudo apt-get install xfce4 sudo service dbus restart 来安装所需要的软 ...
- java面试一日一题:rabbitMQ如何保证消息不丢失
问题:请讲下rabbitMQ如何保证消息不丢失 分析:该问题属于概念题,同时也是一个设计方面的题,牵扯到部分设计层面的东西: 回答要点: 主要从以下几点去考虑, 1.rabbitMQ在保证消息不丢失方 ...
- 题解 CF741E Arpa’s abnormal DNA and Mehrdad’s deep interest
CF741E Arpa's abnormal DNA and Mehrdad's deep interest 记 \(R_{i}\) 表示把 \(T\) 插入在 \(S\) 的第 \(i\) 位后组成 ...
- RHCA rh442 010 文件系统结构 BDP调优 网卡驱动带宽
文件系统结构 用户通过虚拟文件系统,访问底层的文件系统 对于一块磁盘而言,MBR + 分区表记录硬盘的信息 对于一个分区而言,这个分区的第一个块,superblock,超级块,记录分区元数据信息 对于 ...
- Anaconda Navigator打不开
问题描述:之前安装的Anaconda Navigator,好久不用了,今天却打不开了,只有那个绿色圆环图标出现在桌面中央,点一下就没了.但jupyter notebook和Spyder可以正常使用. ...
- 【Vue】MineData 地图接入
一.文档资料: MineData开放平台: https://minedata.cn/md-platform/login/login MineData V2.1.0 接口文档: http://113.1 ...
- 【IDEA】转大小写快速操作
需求场景: 快速修改一些字符全部变成大写,或者小写 例如修改SQL语句,部分字段大写,部分字段小写,需要统一 快捷键: [Ctrl + Shift + U] 演示案例: SELECT ( (SELEC ...
- 【Vue】Re09 Webpack 第一部分(介绍、安装、配置)
一.Webpack的用途 webpack要解决的是统一网页资源的问题 前端工程化出现了很多问题,就是兼容性,浏览器所不能解析 所以需要一个打包,转换等方式处理 二.安装描述介绍 下载安装NodeJS, ...