当前位置: 首页 > news >正文

js 深度克隆

深度克隆(Deep Clone)是指复制一个对象或数组及其所有嵌套结构的副本,使得克隆后的对象与原对象完全独立。JavaScript 提供了一些方法实现深度克隆,但每种方法有其优缺点。

1. 常用方法

1.1 使用 JSON.parseJSON.stringify

这种方法最简单,但有局限性。

const obj = { a: 1, b: { c: 2 } };
const clone = JSON.parse(JSON.stringify(obj));console.log(clone); // { a: 1, b: { c: 2 } }
console.log(clone === obj); // false
console.log(clone.b === obj.b); // false
优点
  • 简单易用。
  • 适用于纯 JSON 格式的数据。
缺点
  • 不支持函数、undefinedSymbol、循环引用等。
  • 日期对象会变成字符串,RegExp 对象会丢失。

1.2 使用 structuredClone

structuredClone 是一种内置的深拷贝方法,支持复杂数据结构。

const obj = { a: 1, b: { c: 2 }, d: new Date() };
const clone = structuredClone(obj);console.log(clone); // { a: 1, b: { c: 2 }, d: Date }
console.log(clone === obj); // false
console.log(clone.b === obj.b); // false
优点
  • 支持更多类型(如 DateRegExpMapSet 等)。
  • 处理循环引用。
缺点
  • 不支持旧版本浏览器。
1.3 使用递归实现深度克隆

通过递归遍历对象和数组,手动实现深拷贝。

function deepClone(obj) {if (obj === null || typeof obj !== 'object') {return obj;}if (obj instanceof Date) {return new Date(obj);}if (obj instanceof RegExp) {return new RegExp(obj);}const clone = Array.isArray(obj) ? [] : {};for (const key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = deepClone(obj[key]);}}return clone;
}const obj = { a: 1, b: { c: 2 }, d: new Date() };
const clone = deepClone(obj);console.log(clone); // { a: 1, b: { c: 2 }, d: Date }
console.log(clone === obj); // false
console.log(clone.b === obj.b); // false
优点
  • 完全控制克隆逻辑。
  • 支持特定类型的处理。
缺点
  • 不支持循环引用,需额外处理。

2. 循环引用处理

对于有循环引用的对象,需要使用 WeakMap 来避免递归陷入死循环。

function deepClone (value, cache = new WeakMap ()) {if (typeof value !== "object" || value === null) {return value;}if (cache.has(value)) {return cache.get(value);}const result = Array.isArray(value) ? [] : {};Object.setPrototypeOf(result, Object.getPrototypeOf(value));cache.set(value, result);for (i in value) {if (value.hasOwnProperty(i)) {result[i] = deepClone(value[i], cache);}}return result;
}const obj = { a: 1 };
obj.b = obj; // 循环引用let clone = deepClone(obj);
console.log(clone); // { a: 1, b: [Circular] }const Person = function(name, age) {this.name = name;this.age = age;
}Person.prototype.a = 100;clone = new Person('a', 12)console.log(clone);

3. 方法对比

方法支持类型处理循环引用性能易用性
JSON.parse/stringify仅支持 JSON 格式简单
structuredClone支持大部分类型简单
手动递归可定制支持类型否(需扩展)中等
Lodash支持复杂结构和循环引用简单

推荐

  • 数据结构简单:使用 JSON.parseJSON.stringify
  • 现代浏览器:使用 structuredClone
  • 复杂场景:使用 Lodash 或手动实现带循环引用处理的深拷贝函数。
http://www.lryc.cn/news/508445.html

相关文章:

  • 深度学习之超分辨率算法——FRCNN
  • 软件测试之压力测试【详解】
  • 电脑出现 0x0000007f 蓝屏问题怎么办,参考以下方法尝试解决
  • 分布式系统架构:限流设计模式
  • G口带宽服务器与1G独享带宽服务器:深度剖析其差异
  • Flamingo:少样本多模态大模型
  • 推荐一款免费且好用的 国产 NAS 系统 ——FnOS
  • 2025系统架构师(一考就过):案例题之一:嵌入式架构、大数据架构、ISA
  • 开机存活脚本
  • 车载网关性能 --- GW ECU报文(message)处理机制的技术解析
  • CosyVoice安装过程详解
  • 传统网络架构与SDN架构对比
  • 如何打造用户友好的维护页面:6个创意提升WordPress网站体验
  • 【hackmyvm】Zday靶机wp
  • redis使用注意哪些事项
  • 步进电机位置速度双环控制实现
  • 优化程序中的数据:从数组到代数
  • 【电商搜索】CRM: 具有可控条件的检索模型
  • 使用 ffmpeg 拼接合并视频文件
  • 【信号滤波 (上)】傅里叶变换和滤波算法去除ADC采样中的噪声(Matlab/C++)
  • Idea内,光标显示问题
  • 回顾 python3中字符串
  • 代码随想录day23 | leetcode 39.组合总和 40.组合总和II 131.分割回文串
  • 全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
  • R机器学习:决策树算法的理解与实操
  • 解锁高效学习之道:从认知升级到实践突破
  • 2024年12月CCF-GESP编程能力等级认证Python编程三级真题解析
  • .NET Core 中使用 C# 获取Windows 和 Linux 环境兼容路径合并
  • 【SH】Ubuntu Server 24服务器搭建MySQL数据库研发笔记
  • 编译原理复习---正则表达式+有穷自动机