JS中对象数组深拷贝方法

structuredClone()

  • JavaScript 中提供了一个原生 API 来执行对象的深拷贝:structuredClone。它可以通过结构化克隆算法创建一个给定值的深拷贝,并且还可以传输原始值的可转移对象。

当对象中存在循环引用 时,仍然可以通过 structuredClone() 进行深拷贝。

javascript 复制代码
      const A = {
        set: new Set([1, 3, 3]),
        map: new Map([[1, 2]]),
        regex: /foo/,
        error: new Error('Hello!')
      }
      A.a = A

      const copied = structuredClone(A)
      console.log(copied)

注意:

原型链不能被遍历或拷贝(克隆的对象将不再是这个类的一个实例(但是这个类的所有有效属性都将被拷贝))

不能拷贝函数、方法DOM节点 、属性描述符、settergetter 以及类似的元数据不能被克隆

支持拷贝的类型:

Array(数组)、ArrayBuffer(数据缓冲区)、Boolean(布尔类型)、DataView(数据视图)、Date(日期类型)、Error(错误类型,包括下面列出的具体类型)、Map(映射类型)、Object (仅指纯对象,如从对象字面量中创建的对象)、原始类型(除symbol外,即 number、string、null、undefined、boolean、BigInt)、RegExp(正则表达式)、Set(集合类型)、TypedArray(类型化数组)。

JSON.parse(JSON.stringify())

使用时需要注意:

JSON.stringify 只能处理基本对象、数组和基本类型,而其他类型的值在转换之后都可能出现出乎意料的结果,例如 Date 会转化为字符串, Set 会转化为 {}

JSON.stringify甚至完全忽略某些内容,比如undefined或函数。

JSON.parse(JSON.stringify(x)) 无法对包含循环引用的对象进行深克隆

javascript 复制代码
      const A = {
        set: new Set([1, 3, 3]),
        map: new Map([[1, 2]]),
        regex: /foo/,
        error: new Error('Hello!')
      }
      A.a = A

      const copied = JSON.parse(JSON.stringify(A))

报错:

所以,如果对象没有上面说的这些情况,使用 JSON.parse(JSON.stringify(x)) 进行深克隆是完全没有问题的。如果有,就可以使用 structuredClone() 来进行深拷贝。

实现深拷贝只需以下三个核心步骤:

  1. 创建出对应数据类型的空白数据。即,若须拷贝的是对象类型数据,则创建一个空白对象,以此类推。
  2. 拷贝目标数据。即把目标数据拷贝到步骤1中创建的空白数据里。
  3. 返回拷贝的数据。
javascript 复制代码
export function deepClone(data: any){
  // 普通类型数据则直接返回
  
  // 循环引用处理
  
  // 1. 创建对应类型的空白数据
  
  // 2. 复制
  
  // 3. 返回
  
}

其他拷贝方式:

Object.assign/解构赋值/arr.concat
当拷贝内容中数据的值都是简单数据类型时,是深拷贝
当拷贝内容中数据的值出现引用数据类型时,引用数据仍然是浅拷贝,只有简单数据类型是深拷贝

转载于:

JavaScript 中更现代的深拷贝方法! - 掘金 (juejin.cn)

相关推荐
Tangyuewei12 分钟前
Java 写 Agent:模型只是组件
java·开发语言
小玮看世界41 分钟前
[Python]从合并区间到传感器融合区:合并区间在传感器区域融合的实际落地
开发语言·python
尾善爱看海1 小时前
前端算法与手写题集
前端·算法
徐小夕1 小时前
JitWord 4.0 万字分享:从协同工具到AI Word操作系统,聊聊3年产品创业史
前端·vue.js·后端
繁星蓝雨1 小时前
C++的设计与演进大纲(如何从C语言一步步成长为C++)
c语言·开发语言·c++·c++历史·c++演进
Evand J2 小时前
【MATLAB例程,图像降噪滤波9】自适应维纳滑动窗口滤波(Wiener)图像降噪、方法对比,有中文注释
开发语言·图像处理·计算机视觉·matlab·滑动窗口·滤波·降噪
杜大哥2 小时前
python程序:如何查看电脑【电池电量的剩余百分比】 和 【是否插入连接着充电器】?
开发语言·python
wuyk5552 小时前
Python网络爬虫入门到实战 第01章:爬虫到底是什么?原理、流程、合法性、风险全解析(零基础必看)
开发语言·爬虫·python
yurenpai(27届找实习中)2 小时前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18
shmily麻瓜小菜鸡3 小时前
JS/TS 易踩坑知识点 — 模块化与工程化类
开发语言·javascript·ecmascript