js的深浅拷贝
深浅拷贝是编程中对数据复制的两种不同方式,它们在处理对象和数组等复合数据结构时尤为重要。下面将详细解释这两种拷贝方式。
浅拷贝(Shallow Copy)
浅拷贝创建了原始对象的一个新实例,但这个新实例的属性只是原始对象属性的引用。如果属性是基本数据类型(如数字、字符串、布尔值),那么它们会被复制;如果属性是引用类型(如对象、数组),则新对象的属性只是指向原始对象属性的引用。
特点:
- 创建新对象,但只复制第一层属性。
- 对于嵌套的对象或数组,新对象的属性与原始对象的属性指向相同的内存地址。
- 修改新对象的嵌套属性,会影响原始对象。
例子:
-
使用
Object.assign():let original = { a: 1, b: { c: 2 } }; let shallow = Object.assign({}, original); shallow.b.c = 3; // 这会同时改变 original.b.c 的值 -
使用扩展运算符:
let original = [1, 2, { d: 4 }]; let shallow = [...original]; shallow[2].d = 5; // 这会同时改变 original[2].d 的值 -
使用数组的
slice()方法:let original = [1, 2, 3]; let shallow = original.slice(); shallow.push(4); // 这不会改变 original,因为数组是新的
深拷贝(Deep Copy)
深拷贝创建了原始对象的一个完全独立的副本,包括所有嵌套的对象和数组。修改新对象的任何属性都不会影响原始对象。
特点:
- 创建一个全新的对象,递归复制所有层级的属性。
- 对于嵌套的对象或数组,新对象的每个属性都是原始属性的独立副本。
- 修改新对象的任何属性,原始对象不受影响。
例子:
-
使用递归函数:
function deepCopy(obj) {if (typeof obj !== 'object' || obj === null) return obj;let clone = Array.isArray(obj) ? [] : {};for (let key in obj) {clone[key] = deepCopy(obj[key]);}return clone; } let original = { a: 1, b: { c: 2 } }; let deep = deepCopy(original); deep.b.c = 3; // 这不会改变 original.b.c 的值 -
使用
JSON.stringify()和JSON.parse():let original = { a: 1, b: { c: 2 } }; let deep = JSON.parse(JSON.stringify(original)); deep.b.c = 3; // 这不会改变 original.b.c 的值
特殊情况
- 函数:深拷贝通常不会复制函数,因为
JSON.stringify()会忽略函数。 - 特殊对象:如
Date,RegExp,Map,Set等,在JSON.stringify()中不会被正确处理。 - 循环引用:
JSON.stringify()无法处理循环引用的对象,会导致错误。
例子 1:函数
let original = { name: 'Alice', greet: function() { console.log('Hello, ' + this.name); } };
let deepCopy = JSON.parse(JSON.stringify(original));deepCopy.greet(); // TypeError: deepCopy.greet is not a function
例子 2:循环引用
let original = {};
original.self = original;let deepCopy = JSON.parse(JSON.stringify(original));
console.log(deepCopy.self === original.self); // 输出: false
例子 3:特殊值
let original = { name: 'Alice', value: undefined };
let deepCopy = JSON.parse(JSON.stringify(original));console.log(deepCopy.value); // 输出: undefined
例子 4:正则表达式
let original = { name: 'Alice', pattern: /abc/ };
let deepCopy = JSON.parse(JSON.stringify(original));console.log(original.pattern.test('abc')); // 输出: true
console.log(deepCopy.pattern.test('abc')); // 输出: false
例子 5:Map 和 Set
let original = { name: 'Alice', map: new Map([['key', 'value']]), set: new Set([1, 2, 3]) };
let deepCopy = JSON.parse(JSON.stringify(original));console.log(original.map.get('key')); // 输出: value
console.log(deepCopy.map.get('key')); // 输出: undefined
区别
通过这些例子,你可以看到深浅拷贝在不同情况下的表现,以及它们在实际应用中的适用性和局限性。
深浅拷贝的区别主要体现在它们复制数据结构的方式和结果上。以下是深浅拷贝的主要区别:
-
复制深度:
- 浅拷贝:只复制了对象的第一层属性。如果对象的属性是引用类型(如数组或对象),浅拷贝只会复制引用,而不是实际的对象或数组。
- 深拷贝:递归地复制了对象的所有层级,包括嵌套的对象或数组。每个属性都是原始属性的独立副本,不共享内存地址。
-
内存地址:
- 浅拷贝:新对象和原始对象共享一些引用类型的属性的内存地址。
- 深拷贝:新对象和原始对象的所有属性都有独立的内存地址,互不影响。
-
独立性:
- 浅拷贝:新对象和原始对象不是完全独立的,修改新对象中引用类型的属性可能会影响原始对象。
- 深拷贝:新对象和原始对象是完全独立的,对新对象的任何修改都不会影响到原始对象。
-
性能:
- 浅拷贝:通常比深拷贝更快,因为它只复制了对象的第一层属性。
- 深拷贝:可能更慢,因为它需要递归地复制所有层级的属性。
-
适用场景:
- 浅拷贝:适用于只需要复制对象的第一层属性,或者对象中不包含复杂的嵌套引用。
- 深拷贝:适用于需要完全独立的副本,特别是当对象包含多层嵌套的引用类型时。
-
实现方式:
- 浅拷贝:可以通过
Object.assign(), 扩展运算符(...),Array.prototype.slice()等方法实现。 - 深拷贝:可以通过递归函数实现,或者使用
JSON.stringify()和JSON.parse()(但有局限性)。
- 浅拷贝:可以通过
-
局限性:
- 浅拷贝:无法处理循环引用,且不会复制函数和特殊对象(如
Date,RegExp,Map,Set等)。 - 深拷贝:使用
JSON.stringify()和JSON.parse()时,无法处理函数、特殊对象和循环引用。
- 浅拷贝:无法处理循环引用,且不会复制函数和特殊对象(如
-
副作用:
- 浅拷贝:由于共享引用,修改新对象可能会产生意外的副作用,影响到原始对象。
- 深拷贝:由于完全独立,修改新对象不会产生副作用。
理解这些区别对于在实际编程中选择合适的数据复制策略非常重要。选择不当可能会导致数据不一致或程序错误。
结论
深浅拷贝的选择取决于你需要复制的数据结构和预期的行为。如果你需要一个完全独立的副本,深拷贝是必要的。如果你只是需要复制第一层的属性,并且不关心嵌套对象的独立性,浅拷贝就足够了。然而,深拷贝也有其局限性,比如无法处理函数和特殊对象,以及循环引用的问题。在实际开发中,了解这些差异对于避免潜在的错误至关重要。
相关文章:
js的深浅拷贝
深浅拷贝是编程中对数据复制的两种不同方式,它们在处理对象和数组等复合数据结构时尤为重要。下面将详细解释这两种拷贝方式。 浅拷贝(Shallow Copy) 浅拷贝创建了原始对象的一个新实例,但这个新实例的属性只是原始对象属性的引…...
实验八: 彩色图像处理
目录 一、实验目的 二、实验原理 1. 常见彩色图像格式 2. 伪彩色图像 3. 彩色图像滤波 三、实验内容 四、源程序和结果 (1) 主程序(matlab (2) 函数FalseRgbTransf (3) 函数hsi2rgb (4) 函数rgb2hsi (5) 函数GrayscaleFilter (6) 函数RgbFilter 五、结果分析 1. …...
Python酷库之旅-第三方库Pandas(048)
目录 一、用法精讲 171、pandas.Series.nlargest方法 171-1、语法 171-2、参数 171-3、功能 171-4、返回值 171-5、说明 171-6、用法 171-6-1、数据准备 171-6-2、代码示例 171-6-3、结果输出 172、pandas.Series.nsmallest方法 172-1、语法 172-2、参数 172-3、…...
springboot爱宠屋宠物商店管理系统-计算机毕业设计源码52726
目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能…...
自训练和增量训练word2vec模型
1、自己准备训练语料文件 根据自己的业务场景准备训练数据,比如用户在商城上的同购行为序列或同浏览行为序列。 我们希望通过自己训练业务相关的语料word2vec模型来获得词嵌入、词相关性查询等。 1.1 准备语料库文件 # 示例:准备自己的一个大规模的语…...
华三路由器开启web访问
配置路由器: # 配置Web用户名为admin,认证密码为admin,服务类型为http,用户角色为network-admin。 [Sysname] local-user admin [Sysname-luser-manage-admin] service-type http [Sysname-luser-manage-admin] authorization…...
C++软件开发值得推荐的十大高效软件分析工具
目录 1、概述 2、高效软件工具介绍 2.1、窗口查看工具SPY 2.2、Dependency Walker 2.3、剪切板查看工具Clipbrd 2.4、GDI对象查看工具GDIView 2.5、Process Explorer 2.6、Prcoess Monitor 2.7、API Monitor 2.8、调试器Windbg 2.9、反汇编工具IDA 2.10、抓包工具…...
vue2老项目中node-sass更换dart-sass
更换原因:node-sass经常会出现node版本问题,就很麻烦 卸载项目中的node-sass sass-loader npm uninstall sass-loader sass 安装dart-sas sass-loader 推荐安装sass1.26.2 sass-loader7.3.1 npm install sass-loader7.3.1 sass1.26.2 从新配置vue.…...
源/目的检查开启导致虚拟IP背后的LVS无法正常访问
情况描述 近期发现48网段主机无法访问8.83这个VIP(虚拟IP),环境是 8.83 绑定了两个LVS实例,然后LVS实例转发到后端的nginx 静态资源;整个流程是,客户端发起对VIP的请求,LVS将请求转发到后端实例…...
类和对象(四)
构造函数中的初始化列表 之前在实现构造函数时,主要是在函数体内进行赋值,而构造函数还有另一种初始化方式,通过初始化列表进行初始化。 初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,…...
<PLC><HMI><汇川>在汇川HMI画面中,如何为UI设置全局样式?
前言 汇川的HMI软件是使用了Qt来编写的,因此在汇川的HMI程序编写过程,是支持使用qt的样式来自定义部件样式的,即qss格式。 概述 汇川的软件本身提供三个系统的style样式,我们可以直接使用,但是,如果系统提供的样式不符合你的需求,那么你可以对其进行修改,或者自己新建…...
在Git项目中添加并应用“.gitignore”文件
在Git项目中添加并应用.gitignore文件 创建或修改.gitignore文件: 在项目的根目录下创建一个名为.gitignore的文件。如果已经有此文件,可以直接修改。 在文件中添加您希望Git忽略的文件和目录。例如: # 忽略所有的log文件 *.log# 忽略所有的…...
LeetCode Hot100 搜索二维矩阵
给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。…...
iOS中的KVO(Key-Value Observing)详解
iOS中的KVO(Key-Value Observing)详解 一、KVO概述 KVO(Key-Value Observing),即键值观察/监听,是苹果提供的一套事件通知机制。它允许一个对象(观察者)观察/监听另一个对象&#…...
算法 —— 暴力枚举
目录 循环枚举 P2241 统计方形(数据加强版) P2089 烤鸡 P1618 三连击(升级版) 子集枚举 P1036 [NOIP2002 普及组] 选数 P1157 组合的输出 排列枚举 P1706 全排列问题 P1088 [NOIP2004 普及组] 火星人 循环枚举 顾名思…...
构造+有序集合,CF 1023D - Array Restoration
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1023D - Array Restoration 二、解题报告 1、思路分析 先考虑合法性检查: 对于数字x,其最左位置和最右位置 之间如果存在数字比x小,则非法 由于q次操作,第q…...
Scrapy 爬取旅游景点相关数据(四)
本节内容主要为: (1)创建数据库 (2)创建数据库表 (3)爬取数据进MYSQL库 1 新建数据库 使用MYSQL数据库存储数据,创建一个新的数据库 create database scrapy_demo;2 新建数据表 CR…...
Vue常用指令及其生命周期
作者:CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 目录 1.常用指令 1.1 v-bind 1.2 v-model 注意事项 1.3 v-on 注意事项 1.4 v-if / v-else-if / v-else 1.5 v-show 1.6 v-for 无索引 有索引 生命周期 定义 流程 1.常用指令 Vue当中的指令…...
简化数据流:Apache SeaTunnel实现多表同步的高效指南
Apache SeaTunnel除了单表之间的数据同步之外,也支持单表同步到多表,多表同步到单表,以及多表同步到多表,下面简单举例说明如何实现这些功能。 单表 to 单表 一个source,一个sink。 从mysql同步到mysql,…...
均匀圆形阵列原理及MATLAB仿真
均匀圆形阵列原理及MATLAB仿真 目录 前言 一、均匀圆阵原理 二、圆心不存在阵元方向图仿真 三、圆心存在阵元方向图仿真 四、MATLAB仿真代码 总结 前言 本文详细推导了均匀圆形阵列的方向图函数,对圆心不放置阵元和圆心放置阵元的均匀圆形阵列方向图都进行了仿…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
