首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的区别

编程知识
2024年09月06日 09:47

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);

image

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);

image

二、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);

image

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'
}

image

1.2. JSON.parse(JSON.stringify())

1.2.1. 支持的类型
  • 数字
  • 字符串
  • 布尔值
  • 数组
  • 普通对象
1.2.2. 不支持的类型
  • Date、Map、Set、RegExp、Function、undefined、symbol、Infinity、NaN、循环引用...

JSON.stringify 详细信息可以看下下面的文章

你需要了解的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
}

image

2. 循环引用

2.1. structuredClone

可以正确处理对象中的循环引用

2.2. JSON.parse(JSON.stringify)

如果对象中存在循环引用,调用 JSON.stringify 会抛出错误,导致克隆失败

image

3. 性能方面

3.1. structuredClone

通常在处理复杂对象时性能更优,特别是包含大量非 JSON 兼容类型的数据时,因为它是为深度克隆设计的原生方法,内部优化了许多复杂场景

3.2. JSON.parse(JSON.stringify)

在处理简单的、JSON 兼容的数据结构时可能性能较好,但在处理复杂对象或非 JSON 兼容类型时效率低下

4. 浏览器兼容

4.1. structuredClone

是一种较新的 API,在某些较旧的浏览器中不被支持

image

image

4.2. JSON.parse(JSON.stringify)

在现代浏览器和较旧的浏览器中都有广泛支持

image

三、总结

  • structuredClone 提供了更广泛的数据类型支持和对循环引用的处理能力,适用于复杂场景
  • JSON.parse(JSON.stringify) 适合处理简单、JSON 兼容的数据结构,但在处理复杂数据类型或循环引用时有局限性
  • 两者都有限制,克隆的时候需要关注下克隆对象的数据类型再做选择

参考

From:https://www.cnblogs.com/risheng/p/18399814
本文地址: http://www.shuzixingkong.net/article/1788
0评论
提交 加载更多评论
其他文章 .NET 多版本兼容的精美 WinForm UI控件库
前言 有粉丝小伙伴在后台留言咨询有没有WinForm 控件库推荐,现在就给安排上。 .NET 平台进行 Windows 应用程序开发的我们来说,找一个既美观又实用的 WinForm UI 控件库至关重要。 本文将介绍 ReaLTaiizor 一款不仅具备精美界面、丰富控件选择,还支持从 .NET F
.NET 多版本兼容的精美 WinForm UI控件库 .NET 多版本兼容的精美 WinForm UI控件库 .NET 多版本兼容的精美 WinForm UI控件库
推荐一款流量录制回放工具:jvm-sandbox-repeater
在软件开发和测试过程中,我们经常会遇到需要对网络请求进行录制和回放的需求,以便进行调试、测试和分析。为了模拟真实的用户请求,我们通常会使用各种流量录制回放工具来记录并重放网络请求。 其中,jvm-sandbox-repeater 是一款功能强大的流量录制回放工具,可以帮助我们轻松实现对网络请求的录制
推荐一款流量录制回放工具:jvm-sandbox-repeater 推荐一款流量录制回放工具:jvm-sandbox-repeater 推荐一款流量录制回放工具:jvm-sandbox-repeater
ComfyUI 基础教程(二) —— Stable Diffusion 文生图基础工作流及常用节点介绍
上一篇文章讲解述首次启动 ComfyUI 会自动打开一个最基础的文生图工作流。实际上,后续我们可以通过菜单选项,或者快捷键 ctrl + D来打开这个默认工作流。默认工作流如下: 这是一个最基础的文生图工作流,本文通过对这个工作流的讲解,让大家对 ComfyUI 工作流有一个基本的认识。 一、文生图
ComfyUI 基础教程(二) —— Stable Diffusion 文生图基础工作流及常用节点介绍 ComfyUI 基础教程(二) —— Stable Diffusion 文生图基础工作流及常用节点介绍 ComfyUI 基础教程(二) —— Stable Diffusion 文生图基础工作流及常用节点介绍
从0认识竞品分析(附实战分析抖音)
什么是竞品分析? 顾名思义,是对竞争对手的产品进行比较分析的过程,一种带有主观性的横向分析过程;通过对多个产品的整体架构、功能、商业模式、产品策略等多维度的横向对比分析,从而获得目的性的结论。那如何分析呢?我们这里按照下面几个点来一一展开:**明确目的,行业分析,确定竞品,确定维度,搜索数据,对比
从0认识竞品分析(附实战分析抖音)
感知机模型
一、概述 感知机模型(Perceptron Model)也叫做神经元模型,设计灵感即来自于生物神经元的运行机制,依次完成信息接收、处理、输出的过程。当前大放异彩的各种人工神经网络模型即由一个个人工神经元构成,因此,本文介绍的感知机模型(神经元模型)就是各种神经网络模型的基本单元。 二、模型原理 模型
感知机模型 感知机模型 感知机模型
R-Adapter:零样本模型微调新突破,提升鲁棒性与泛化能力 | ECCV 2024
大规模图像-文本预训练模型实现了零样本分类,并在不同数据分布下提供了一致的准确性。然而,这些模型在下游任务中通常需要微调优化,这会降低对于超出分布范围的数据的泛化能力,并需要大量的计算资源。论文提出新颖的Robust Adapter(R-Adapter),可以在微调零样本模型用于下游任务的同时解决这
R-Adapter:零样本模型微调新突破,提升鲁棒性与泛化能力 | ECCV 2024 R-Adapter:零样本模型微调新突破,提升鲁棒性与泛化能力 | ECCV 2024 R-Adapter:零样本模型微调新突破,提升鲁棒性与泛化能力 | ECCV 2024
C++创建与调用dll动态链接库(MinGW64 Dev-C++)
本文使用的是dev-c++,如果涉及到VC++中不一样的操作,也会适当进行区分。 项目一:创建DLL 1、创建一个DLL类型的项目,当前命名为dlltest,并选择合适的路径进行保存。 2、在生成的预设置代码中,加入如下代码 //这是头文件dll.h #ifndef _DLL_H_ #define
C++创建与调用dll动态链接库(MinGW64 Dev-C++) C++创建与调用dll动态链接库(MinGW64 Dev-C++) C++创建与调用dll动态链接库(MinGW64 Dev-C++)
WPF 保姆级教程怎么实现一个树形菜单
先看一下效果吧: 我们直接通过改造一下原版的TreeView来实现上面这个效果 我们先创建一个普通的TreeView 代码很简单: <TreeView> <TreeViewItem Header="人事部"/> <TreeViewItem Heade
WPF 保姆级教程怎么实现一个树形菜单 WPF 保姆级教程怎么实现一个树形菜单 WPF 保姆级教程怎么实现一个树形菜单