javaScript中的浅拷贝和深拷贝详解

news/2024/10/17 11:08:52/

在 JavaScript 中,浅拷贝深拷贝 的主要区别在于它们如何处理对象中的嵌套对象(即对象的属性也是对象的情况)。

1. 浅拷贝

浅拷贝只复制对象的第一层属性。如果对象的属性是一个引用类型(如对象或数组),浅拷贝只会复制该引用的地址,而不是实际的值。这意味着,如果你修改了拷贝对象中引用类型的属性,原对象中的该属性也会被修改。

常见的浅拷贝方式:
  • Object.assign()
  • 扩展运算符 ...
javascript">let obj1 = { a: 1, b: { c: 2 } };
let obj2 = Object.assign({}, obj1);
// 或者
let obj3 = { ...obj1 };// 修改 obj2 中的 b 属性
obj2.b.c = 3;console.log(obj1.b.c); // 输出 3,因为 obj1 和 obj2 共享同一个 b 对象的引用

2. 深拷贝

深拷贝会递归地复制对象的所有层次,包括嵌套的对象和数组。这意味着拷贝后的对象和原对象完全独立,修改拷贝对象的任意部分都不会影响原对象。

实现深拷贝的常见方法:
1. 使用 JSON.stringify()JSON.parse()

这是一种简单但不太灵活的方法,它会将对象序列化为 JSON 字符串,再解析为新对象。它有一些局限性,比如不能处理 undefined、函数、循环引用等复杂数据结构。

javascript">let obj1 = { a: 1, b: { c: 2 } };
let obj2 = JSON.parse(JSON.stringify(obj1));// 修改 obj2 中的 b 属性
obj2.b.c = 3;console.log(obj1.b.c); // 输出 2,因为 obj1 和 obj2 是完全独立的
2. 递归实现深拷贝:

为了实现更健壮的深拷贝,可以手动递归地复制对象的每一层属性。

javascript">function deepClone(obj) {// 如果不是对象或者是 null,直接返回原值if (typeof obj !== "object" || obj === null) {return obj;}// 创建一个新的对象或数组,取决于原始对象的类型let newObj = Array.isArray(obj) ? [] : {};for (let key in obj) {// 确保该属性是对象自己的(而不是继承的)if (obj.hasOwnProperty(key)) {// 递归地拷贝属性值newObj[key] = deepClone(obj[key]);}}return newObj;
}let obj1 = { a: 1, b: { c: 2 } };
let obj2 = deepClone(obj1);obj2.b.c = 3;console.log(obj1.b.c); // 输出 2,拷贝是深层的
3. 使用 Lodash 库的 cloneDeep 方法:

Lodash 是一个流行的 JavaScript 工具库,它提供了一个强大的深拷贝方法 _.cloneDeep(),可以处理复杂的数据结构。

javascript">let _ = require('lodash'); // 引入 lodash 库
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = _.cloneDeep(obj1);obj2.b.c = 3;console.log(obj1.b.c); // 输出 2

深拷贝和浅拷贝的应用场景:

  • 浅拷贝 适合简单的、没有嵌套对象的数据结构。
  • 深拷贝 在处理包含复杂对象、嵌套对象或数组时更为合适,因为这确保了数据的独立性。

总结:

  • 浅拷贝:只复制第一层的属性,嵌套对象引用仍然指向原来的对象。
  • 深拷贝:递归复制所有层次的属性,拷贝后的对象与原对象完全独立。

http://www.ppmy.cn/news/1532681.html

相关文章

【图像处理】多幅不同焦距的同一个物体的平面图象,合成一幅具有立体效果的单幅图像原理(一)

合成一幅具有立体效果的单幅图像,通常是利用多个不同焦距的同一物体的平面图像,通过图像处理技术实现的。以下是该过程的基本原理: 1. 立体视觉原理 人眼的立体视觉是通过双眼观察物体的不同视角而获得的。两只眼睛的位置不同,使…

Go基础学习05-数组和切片关系深度解析

切片和数组的联系 数组(array)和切片(slice)都属于集合类的类型,它们的值也都可以用来存储某一种类型的值(或者说元素)。数组和切片最重要的不同在于: 数组类型的值的长度是固定的…

模拟实现(优先级队列)priority_queue:优先级队列、仿函数、 反向迭代器等的介绍

文章目录 前言一、优先级队列二、仿函数三、 反向迭代器总结 前言 模拟实现(优先级队列)priority_queue:优先级队列、仿函数、 反向迭代器等的介绍 一、优先级队列 优先级队列本质是一个堆,使用vector容器进一步改进进行实现&am…

TFTP协议

目录 一、TFTP协议概述 1.1 TFTP协议简介 1.2 TFTP协议特点 二、TFTP协议原理 2.1 TFTP协议工作流程 2.2 TFTP协议数据包格式 三、TFTP协议应用场景 3.1 网络设备配置文件传输 3.2 虚拟机镜像文件传输 3.3 IoT设备固件升级 四、TFTP协议优化方法 4.1 增加超时重传机…

56 mysql 用户权限相关的实现

前言 这里讨论 mysql 的权限相关处理 使用如下语句创建 tz_test 用户, 并赋予他 test_02 数据库的查询权限 create user tz_test% identified by tz_test; grant select on test_02.* to tz_test%; 查询目标数据表, 数据如下, tz_test_02 UPDATE command denied to user …

QT 界面编程中使用协程

QT 界面编程中使用协程 一、概述二、集成2.1、编译 Acl2.2、将 Acl 库集成到 QT 项目中2.3、开始编写代码2.3.1、QT 程序初始化时初始化 Acl 协程2.3.2、在界面中创建协程2.3.3、界面程序退出前需要停止协程调度2.3.4、在界面线程中下载数据2.3.5、在协程中延迟创建窗口 2.4、效…

HUAWEI WATCH GT 系列安装第三方应用

文章目录 适用机型概述官方文档从源码构建 hap 文件和对源码签名下载和安装DevEco Studio下载和安装首次启动推荐:设置IDE推荐的兼容版本环境(可选)安装并启用中文菜单插件 使用DevEco Studio打开项目并进行构建构建问题解决一、生成密钥和证…

数据分析师之Excel学习

前言 excel作为职场人来说,已经是人人必备的技能了,所以还不知道这个的小伙伴,一定要抓紧时间学习,紧跟时代的步伐。 Excel 几个重要的版本 97-2003版本是国内最早流行的版本 .xlsx后缀的表格文件,基本是07版本及…