首页 > 编程语言 >JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的区别

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

时间:2024-09-06 10:48:02浏览次数:15  
标签:stringify const 克隆 structuredClone JSON new

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 兼容的数据结构,但在处理复杂数据类型或循环引用时有局限性
  • 两者都有限制,克隆的时候需要关注下克隆对象的数据类型再做选择

参考

标签:stringify,const,克隆,structuredClone,JSON,new
From: https://www.cnblogs.com/risheng/p/18399814

相关文章

  • SpringMVC-05-Json
    1、什么是JSON?JSON:JavaScriptObjectNotation(JS对象描述法)。JSON是一种存储和交换数据的语法。JSON是通过JS对象描述法书写的文本,用字面文本的形式来表示一个JS对象2、为什么要使用JSON?JSON是一种轻量级的数据交换格式,伴随着JavaScript语言的火爆,目前使用特别广泛。......
  • 使用CJson编写多个节点嵌套的程序代码
    CJson(或者更常见的名称可能是cJSON,一个流行的C语言JSON解析库)允许你以程序化的方式处理JSON数据,包括创建、解析、修改和删除JSON对象。这里我将展示如何使用cJSON库来创建一个包含多个嵌套节点的JSON对象。首先,确保你已经安装了cJSON库。如果你使用的是像Ubuntu这样的Linux......
  • 使用vue-json-pretty和vue-json-schema-editor-visual封装一个可视化json数据编辑器及
    一、前言        最近做了一个需求,要求实现可以对json结构进行编辑保存及字段级别的权限管控,结合目前已有的轮子和当前项目的结构,决定使用vue-json-pretty和vue-json-schema-editor-visual来实现效果如下组件支持修改左侧json数据,自动生成右侧树。也支持修改右侧树......
  • 前端常用的echart获取地图json方法
    一、世界地图,不细分国家相关链接:geojson在线绘制 Json文件链接:world-min.json二、世界地图,包含各个国家 Json文件链接:world.json三、中国地图,省市区县(阿里DataV.GeoAtlas)相关链接:阿里DataV.GeoAtlas在线绘制  Json文件链接:china-min.json、china.json修复右手定......
  • MySQL JSON 数据类型
    JSON数据类型是MySQL5.7.8开始支持的。在此之前,只能通过字符类型(CHAR,VARCHAR或TEXT)来保存JSON文档。相对字符类型,原生的JSON类型具有以下优势:在插入时能自动校验文档是否满足JSON格式的要求。优化了存储格式。无需读取整个文档就能快速访问某个元素的值。在JS......
  • vscode launch.json 模板备忘
    {//UseIntelliSensetolearnaboutpossibleattributes.//Hovertoviewdescriptionsofexistingattributes.//Formoreinformation,visit:https://go.microsoft.com/fwlink/?linkid=830387"version":"0.2.0",&quo......
  • 当采用 JSON 格式的数据进行响应时,对象是否需要序列化取决于什么?
    目录1.使用JSON库进行序列化2.使用Java的默认序列化机制当采用JSON格式的数据进行响应时,对象是否需要序列化取决于你是如何将对象转换为JSON格式的。在Java中有两种情况:1.使用JSON库进行序列化如果你使用的是像Jackson、Gson或Fastjson这样的JSON处理库......
  • 使用 niljson 处理 Go 语言中 JSON 的空值类型
    使用niljson处理Go语言中JSON的空值类型原创 源自开发者 源自开发者  2024年09月03日11:43 广东 听全文源自开发者专注于提供关于Go语言的实用教程、案例分析、最新趋势,以及云原生技术的深度解析和实践经验分享。321篇原创内容公众号在使用G......
  • 【Python技术学习】- python JSON 数据解析
    JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。Python3中可以使用json模块来对JSON数据进行编解码,它包含了两个函数:json.dumps(): 对数据进行编码。json.loads(): 对数据进行解码。在json的编解码过程中,Python的原始类型与json类型会相互......
  • MySQL 允许你在 JSON 数据上创建索引
    MySQL允许你在JSON数据上创建索引测试用例CREATETABLE`student`(`id`intNOTNULLAUTO_INCREMENT,`name`varchar(255)DEFAULTNULL,`age`intDEFAULTNULL,`courses`jsonDEFAULTNULL,`address`jsonDEFAULTNULL,PRIMARYKEY(`id`))ENGINE=Inn......