JavaScript 对象复制:浅拷贝与深拷贝

news2025/4/20 4:03:42

JavaScript 对象复制:浅拷贝与深拷贝使用说明

在 JavaScript 中,对象复制分为 浅拷贝 和 深拷贝,两者的核心区别在于是否递归复制嵌套的引用类型属性。以下是详细说明和示例:


一、浅拷贝(Shallow Copy)

特点:仅复制对象的第一层属性,若属性是引用类型(如对象、数组),则拷贝的是引用地址。修改嵌套的引用属性会影响原对象。

常用方法:
  1. Object.assign()

    javascript

    const obj = { a: 1, b: { c: 2 } };
    const shallowCopy = Object.assign({}, obj);
    shallowCopy.b.c = 99; // 原对象的 obj.b.c 也会变为 9
    或者
    const shallowCopy = {};
    Object.assign(shallowCopy, obj);
    
    也可以复制 reactive 或 ref 创建的响应式对象
    const refObj = ref({});
    Object.assign(refObj.value, proxyObj);
    
  2. 展开运算符 ...

    javascript

    const obj = { a: 1, b: { c: 2 } };
    const shallowCopy = { ...obj };
  3. 数组浅拷贝

    javascript

    const arr = [1, 2, { d: 3 }];
    const newArr = arr.slice(); // 或 [...arr], Array.from(arr)
适用场景:
  • 对象属性无嵌套引用类型。

  • 需要快速复制且性能敏感的场景。


二、深拷贝(Deep Copy)

特点:完全复制对象及其所有嵌套属性,新旧对象完全独立,互不影响。

常用方法:
  1. JSON.parse(JSON.stringify())

    javascript

    const obj = { a: 1, b: { c: 2 }, d: new Date() };
    const deepCopy = JSON.parse(JSON.stringify(obj));
    
    如果是 reactive 或 ref 创建的响应式对象,先通过 toRaw 转为 普通对象,再进行拷贝。
    例如:
    const deepCopy = JSON.parse(JSON.stringify(toRaw(proxyObj))); // deepCopy 为普通对象
    const deepCopy = reactive(JSON.parse(JSON.stringify(toRaw(proxyObj)))); // deepCopy 为 reactive 响应式对象 Proxy(Object)
    const deepCopy = ref(JSON.parse(JSON.stringify(toRaw(proxyObj)))); // deepCopy 为ref响应式对象 RefImpl
    

    局限性

    • 忽略 undefined、函数、Symbol。

    • 破坏特殊对象(如 Date 转为字符串,RegExp 转为空对象)。

    • 无法处理循环引用。

  2. structuredClone()(现代浏览器/Node.js 17+)

    javascript

    const obj = { a: 1, b: { c: 2 } };
    const deepCopy = structuredClone(obj); // 支持更多类型,如 Date、Set、Map
    
    如果是 reactive 或 ref 创建的响应式对象,先通过 toRaw 转为 普通对象,再进行拷贝。
    例如:
    const deepCopy = structuredClone(toRaw(proxyObj)); // deepCopy 为普通对象
    const deepCopy = reactive(structuredClone(toRaw(proxyObj))); // deepCopy 为 reactive 响应式对象 Proxy(Object)
    const deepCopy = ref(structuredClone(toRaw(proxyObj))); // deepCopy 为ref响应式对象 RefImpl
    
  3. Lodash 的 cloneDeep()

    javascript

    import { cloneDeep } from 'lodash';
    const obj = { a: 1, b: { c: 2 } };
    const deepCopy = cloneDeep(obj); // 处理复杂对象(函数、循环引用等)
  4. 手动递归实现

    javascript

    function deepClone(source, map = new WeakMap()) {
      if (source === null || typeof source !== 'object') return source;
      if (map.has(source)) return map.get(source); // 解决循环引用
      const target = Array.isArray(source) ? [] : {};
      map.set(source, target);
      for (const key in source) {
        if (source.hasOwnProperty(key)) {
          target[key] = deepClone(source[key], map);
        }
      }
      return target;
    }
适用场景:
  • 对象包含多层嵌套引用。

  • 需要完全独立副本(如状态管理、撤销操作)。


三、如何选择?

方法类型优点缺点
Object.assign浅拷贝简单快速无法处理嵌套引用
JSON 序列化深拷贝原生支持丢失特殊类型,无法处理循环引用
structuredClone深拷贝支持更多类型兼容性要求(IE 不支持)
Lodash cloneDeep深拷贝功能全面需引入第三方库

四、注意事项

  1. 循环引用:手动实现或第三方库需处理对象间的循环引用。

  2. 特殊类型:根据数据类型选择方法(如 structuredClone 支持 Date、Map 等)。

  3. 性能:深拷贝对大型对象有较高开销,优先考虑浅拷贝。


总结

  • 浅拷贝:用 Object.assign 或 ...,适合简单对象。

  • 深拷贝:优先使用 structuredClone 或 Lodash,复杂场景手动实现需谨慎。

通过合理选择拷贝方式,可避免数据意外修改,提升代码健壮性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2338453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MTK-Android12 13 屏蔽掉Viewing full screen

去掉ROOM 开机第一次提示全屏弹框 文章目录 需求参考资料修改文件实现方案 解决思路grep 源码查找信息grep 查找 grep -rn "Viewing full screen" 找string 字段grep 查找 grep -rn immersive_cling_title 布局grep 查找 grep -rn layout.immersive_mode_cling 对应的…

GitHub创建远程仓库

使用GitHub创建远程仓库:从零开始实现代码托管与协作 前言 在当今软件开发领域,版本控制系统已成为开发者必备的核心工具。作为分布式版本控制系统的代表,Git凭借其强大的分支管理和高效的协作能力,已成为行业标准。而GitHub作为…

【AI部署】腾讯云GPU -—SadTalker的AI数字人访问web服务—未来之窗超算中心

访问部署在Cloud Studio上的web服务 当你把该项目部署在本地时,访问该服务的请求地址为http://localhost:8080/hello;当你把该项目部署在Cloud Studio工作台启动时,要想访问到该服务,需要先在工作台右侧打开访问链接面板&#xff…

fastdds:传输层SHM和DATA-SHARING的区别

下图是fastdds官方的图,清晰地展示了dds支持的传输层: 根据通信双方的相对位置(跨机器、同机器跨进程、同进程)的不同选择合适的传输层,是通信中间件必须要考虑的事情。 跨机器:udp、tcp 跨机器通信,只能通过网络, f…

树莓派_利用Ubuntu搭建gitlab

树莓派_利用Ubuntu搭建gitlab 一、给树莓派3A搭建基本系统 1、下载系统镜像 https://cdimage.ubuntu.com/ubuntu/releases/18.04/release/ 2、准备系统SD卡 二、给树莓派设备联网 1、串口后台登录 使用串口登录后台是最便捷的,因为前期网络可能不好直接成功 默…

ARINC818协议(三)

源特定参数 源特定参数被定义,用于在源和目的之间进行传输 源特定参数包括初始化,合适的解释,周期性的验证。 gamma or palette tables:伽马或者调色板 color format:颜色格式 Brightness and backlight control :亮度…

得佳胜哲讯科技 SAP项目启动会:胶带智造新起点 数字转型新征程

在全球制造业加速向数字化、智能化转型的浪潮中,胶带制造行业正迎来以“自动化生产、数据化运营、智能化决策”为核心的新变革。工业互联网、大数据分析与智能装备的深度融合,正推动胶带制造从传统生产模式向“柔性化生产精准质量控制全链路追溯”的智慧…

万字解析TCP

通过学习视频加博客的组合形式,整理了一些关于TCP协议的知识。 *图源:临界~的csdn博客。 一、TCP建立连接 TCP的建立连接,大致可以分为面向连接、TCP报文结构、TCP的三次握手、TCP的建立状态、SYN泛洪攻击。 1.1、面向连接 面向连接 --- …

2025年大数据实训室建设及大数据实训平台解决方案

一、引言 在数字化浪潮中,大数据技术已成为推动各行业创新发展的核心驱动力。从金融领域的风险预测到医疗行业的精准诊断,从电商平台的个性化推荐到交通系统的智能调度,大数据的应用无处不在。据权威机构预测,到 2025 年&#xf…

贪心、动态规划、其它算法基本原理和步骤

目录 1. 贪心1.1 贪心算法的基本步骤1.2 贪心算法实战1.2.1 贪心的经典问题1.2.2 贪心解决数组与子序列问题1.2.3 贪心解决区间调度问题1.2.4 贪心解决动态决策问题1.2.5 贪心解决一些复杂场景应用 2. 动态规划2.1 动态规划的基本步骤和一些优化2.2 动态规划实战2.2.1 斐波那契…

python-各种文件(txt,xls,csv,sql,二进制文件)读写操作、文件类型转换、数据分析代码讲解

1.文件txt读写标准用法 1.1写入文件 要读取文件,首先得使用 open() 函数打开文件。 file open(file_path, moder, encodingNone) file_path:文件的路径,可以是绝对路径或者相对路径。mode:文件打开模式,r 代表以…

ctfshow-大赛原题-web702

因为该题没有理解到位,导致看wp也一直出错,特此反思一下。 参考yu22x师傅的文章 :CTFSHOW大赛原题篇(web696-web710)_ctfshow 大赛原题-CSDN博客 首先拿到题目: // www.zip 下载源码 我们的思路就是包含一个css文件,…

Triton(2)——Triton源码接结构

1 triton 3.0.0 源码结构 triton docs/:项目文档 cmake/:构建配置相关 bin/:工具、脚本 CmakeLists.txt:cmake 配置文件 LSCENSE README.md Pyproject.toml:python 项目配置文件 utils/:项目配置文…

容器docker入门学习

这里写目录标题 容器容器的软件厂商 dockerdocker引擎 虚拟化虚拟化技术 docker安装详解1、安装检查2、安装yum相关的工具3、安装docker-ce软件4、查看docker版本5、启动docker服务6、设置docker开机启动7、查看有哪些docker容器运行进程8、查看容器里有哪些镜像9、下载nginx软…

HarmonyOS NEXT开发教程:全局悬浮窗

今天跟大家分享一下HarmonyOS开发中的悬浮窗。 对于悬浮窗,可能有的同学会想到使用层叠布局是否可以实现,将悬浮窗叠在导航栏组件Tabs上,像这样: Stack({alignContent:Alignment.BottomEnd}){Tabs({barPosition:BarPosition.End…

解锁元生代:ComfyUI工作流与云原生后端的深度融合

目录 蓝耘元生代:智算新势力崛起​ ComfyUI 工作流创建详解​ ComfyUI 初印象​ 蓝耘平台上搭建 ComfyUI 工作流​ 构建基础工作流实操​ 代码示例与原理剖析​ 云原生后端技术全景 云原生后端概念解析​ 核心技术深度解读​ 蓝耘元生代中两者的紧密联系​…

STM32 基本GPIO控制

目录 GPIO基础知识 ​编辑IO八种工作模式 固件库实现LED点灯 蜂鸣器 按键基础知识 ​编辑继电器 震动传感器 433M无线模块 GPIO基础知识 GPIO(General-Purpose input/output,通用输入/输出接口) 用于感知外部信号(输入模式)和控制外部设备&…

汽车免拆诊断案例 | 2019款大众途观L车鼓风机偶尔不工作

故障现象 一辆2019款大众途观L车,搭载DKV发动机和0DE双离合变速器,累计行驶里程约为8万km。车主进厂反映,鼓风机偶尔不工作。 故障诊断  接车后试车,鼓风机各挡位均工作正常。用故障检测仪检测,空调控制单元&#x…

FastAPI与SQLAlchemy数据库集成

title: FastAPI与SQLAlchemy数据库集成 date: 2025/04/17 15:33:34 updated: 2025/04/17 15:33:34 author: cmdragon excerpt: FastAPI与SQLAlchemy的集成通过创建虚拟环境、安装依赖、配置数据库连接、定义数据模型和实现路由来完成。核心模块包括数据库引擎、会话工厂和声…

免费将静态网站部署到服务器方法(仅支持HTML,CSS,JS)

原视频链接:把HTML免费部署到网站上,实现别人也能访问的教程来啦QAQ_哔哩哔哩_bilibili 注意:仅支持HTML、CSS、JS。不支持Vue等框架。 1.打开网站www.wordpress.org 点击红框按钮 点击红框按钮下载wordpress模板文件并解压。 将自己编写的…