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

深拷贝与浅拷贝

浅拷贝(Shallow Copy)

只复制第一层属性。若属性为‌基本类型‌(如numberstring),则复制值;若属性为‌引用类型‌(如对象、数组),则‌仅复制引用地址‌,新旧对象共享该嵌套数据,如果修改嵌套属性会影响原对象

浅拷贝的方法

对象:1.Object.assign({}, obj)。2.扩展运算符{ ...obj }

var a = { count: 1, deep: { count: 2 } } var b = {...a};//扩展运算符 var c = Object.assign({}, a) a.deep.count = 5 console.log(b.deep.count) // 5 console.log(c.deep.count) // 5

数组:

  • arr.slice()截取子数组、浅拷贝,支持负索引(从末尾算起)
  • arr.concat()拼接多个数组/值、浅拷贝,可直接传入非数组元素,自动展开
  • Array.from(arr)类数组转数组、带映射的转换,可传入映射函数,支持thisArg
const arr = [1, 2, 3, 4, 5]; const arr2 = arr.slice(); const arr3 = arr.concat(); const arr4 = Array.from(arr); arr.push(6); console.log(arr);// [1, 2, 3, 4, 5, 6] console.log(arr2); // [1, 2, 3, 4, 5](原数组不变) console.log(arr3); // [1, 2, 3, 4, 5](原数组不变) console.log(arr4); // [1, 2, 3, 4, 5](原数组不变)

深拷贝(Deep Copy)

递归复制所有层级‌,包括嵌套对象和数组;新对象与原对象‌完全独立‌,互不影响;修改副本不会影响原对象

深拷贝的方法

1.JSON.parse(JSON.stringify(obj))

简单易用,但‌无法处理函数、undefinedSymbolDateRegExp、循环引用等。使用JSON.stringifyJSON.parse方法时,会丢失对象的原型链、函数以及undefined

var a = { count: 1, deep: { count: 2 } } var b = JSON.parse(JSON.stringify(a)); a.deep.count = 5; console.log(b.deep.count) // 2
2.手写递归

这是最常用的方法之一,可以处理大部分数据结构,但需注意处理循环引用。递归方法需要考虑循环引用的问题,通常通过使用WeakMap来记录已拷贝过的对象来解决

function deepCloneWithCycle(obj, map = new WeakMap()) { // 基本类型或 null,直接返回 if (typeof obj !== 'object' || obj === null) { return obj; } // 如果已拷贝过,直接返回缓存结果 if (map.has(obj)) { return map.get(obj); } let result; if (obj instanceof Date) { result = new Date(obj); } else if (obj instanceof RegExp) { result = new RegExp(obj.source, obj.flags); //obj.source:返回该正则表达式的‌模式字符串‌(即正则内容本身,不包括斜杠和标志) //obj.flags:返回该正则表达式使用的‌标志字符串‌(如 "g"、"i"、"m" 等,或组合如 "gi") } else if (Array.isArray(obj)) { result = []; for (let i = 0; i < obj.length; i++) { result[i] = deepCloneWithCycle(obj[i], map); } } else { result = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { result[key] = deepCloneWithCycle(obj[key], map); } } } // 缓存当前对象的拷贝 map.set(obj, result); return result; } const a = { date: new Date(), deep: { count: 2 } }; const b = deepCloneWithCycle(a); a.deep.count = 5; console.log(b.deep.count) // 2
3.structuredClone()(推荐用于现代环境)
const a = { date: new Date(), deep: { count: 2 } }; const b = structuredClone(a); a.deep.count = 5; console.log(b.deep.count) // 2
4.利用第三方库(如lodash的_.cloneDeep)
http://www.jsqmd.com/news/522613/

相关文章:

  • 再互动剖析哈尔滨啤酒扫码领红包80%中奖率背后的三层逻辑 - 品牌智鉴榜
  • 跨平台协同:AMESim与Matlab/Simulink联合仿真环境搭建与实战指南
  • 用GraphRAG 2.0.0+阿里云API,给你的本地文档库做个“知识大脑”(附四种查询方法对比)
  • 南方电网电费监控Home Assistant集成:5分钟实现智能用电管理
  • 深度解析安科士800G OSFP 2FR4光模块,解锁高速互联核心技术
  • 大模型学习day1:prompt engneering
  • 别只盯着80端口:Tomato靶机渗透中那些容易被忽略的‘边路’突破口(2211端口与日志审计)
  • refine 命令:增量扩展 CLI 覆盖面的正确姿势
  • 2026 企业网盘选型指南:大型企业只需关注这 5 款主流方案的实测差异
  • QGIS天地图插件进阶玩法:多Key轮换+省级节点加速配置指南
  • Advanced Techniques in Hate Speech Detection: From Embeddings to Model Design
  • FireRed-OCR Studio一文详解:像素风UI如何通过CSS Grid实现响应式预览布局
  • 从零开始:在VS2019上玩转LVGL8.1仿真的完整指南(含常见问题解决方案)
  • Windows家庭版也能用远程桌面!RDP Wrapper避坑安装教程(2023最新版)
  • 用Python实战理解互信息:从数据科学到机器学习应用
  • 你的服务器真的安全吗?手把手教你用PAM模块给SSH登录上把“锁”(防暴力破解实战配置)
  • 人该怎样活着呢?版本69.9
  • 【Simulink实战】FCS-MPC在并网逆变器电流控制中的核心算法与仿真实现
  • YOLOv5训练避坑指南:如何通过调整loss权重参数显著提升小目标检测效果
  • YOLO12双服务模式详解:FastAPI接口与Gradio可视化界面全攻略
  • Open Interpreter架构解析:本地化代码执行引擎的设计哲学与部署实践
  • SUNFLOWER MATCH LAB 数据采集利器:Python爬虫构建植物图像数据集
  • 基于带遗忘因子的最小二乘法估计轮胎侧偏刚度(线性区) 说明:用带遗忘因子的递归最小二乘法进行线...
  • AI驱动网络攻防军备竞赛的演进机理与防御范式重构
  • 清音听真深度体验:专业术语、地方口音识别实测报告
  • 深耕垂直赛道,匠造靠谱品质——宏洛图,化妆品及保健品食品包装设计优选服务商 - 宏洛图品牌设计
  • STM32 vs 8051:现代嵌入式项目选型的工程决策逻辑
  • CLIP-GmP-ViT-L-14图文匹配工具从零开始:无需Python基础的Streamlit交互体验
  • Kubeadm初始化踩坑记:containerd默认禁用CRI的快速修复方案
  • 2026年类似Confluence的工具推荐:技术团队知识沉淀通用系统工具对比分析 - 品牌推荐