JavaScript中的拷贝技术探秘:浅拷贝与深拷贝的奥秘

最新技术资源(建议收藏)
https://www.grapecity.com.cn/resources/

前言

JavaScript中的浅拷贝和深拷贝是非常重要的概念,它们在处理对象和数组时具有不同的作用。在编程中,经常需要复制数据以便进行各种操作,但必须注意拷贝的方式,以确保得到预期的结果。

浅拷贝是创建一个新对象或数组,并将原始对象或数组的引用复制给它。这意味着新对象和原始对象将共享相同的内存地址,修改其中一个对象的属性或元素也会影响另一个对象。相反,深拷贝是创建一个完全独立的对象或数组,新的拷贝将具有与原始对象或数组相同的值,但是它们在内存中是彼此独立的,相互之间的修改不会互相影响。

本文小编将为大家介绍JavaScript中实现浅拷贝和深拷贝的不同方法,并提供示例代码作为辅助。

基本拷贝

下面是一个基本的拷贝,新的拷贝对象会专门开辟一块内存空间——二者的类型、值都是独立可变的,换句话说,他们是通过将值传递给新对象完成拷贝的。

//原始值拷贝
let x = 400
let y = x
x = "This string"
console.log(y)  //400
console.log(x)  //This string

当y被创建时,它的值被赋予了x的值(因为这是在运行时,x被重新赋值之前)。这里重要的一点是,读者可以通过创建另一个变量并将其分配给要复制的变量来快速将原始数据类型的精确值复制到单独的内存空间中。请注意它是如何实例化的——const 不允许再进行更改。

​ (内存分配和原始赋值的视觉进展)

//小编可以走的更深一些,在上面的代码中,再将x设置为原始数据类型;
//当然了,小编都知道它们是在不同的内存空间,只不过值是相同的
let x = 400
let y = x
x = "This string"
console.log(y)  //400
console.log(x)  //This string
x = 400
console.log(x)  // 400
console.log(y)  // 400

浅拷贝

以下是一个展示浅拷贝的示例。在此示例中,拷贝了一个包含文字的浅对象。由于浅拷贝只会复制原始对象的引用而非值本身,所以被拷贝的对象和原始对象将共享相同的内存空间,即它们的值也将相同。需要注意的是,在 JavaScript 中,“浅对象”是指一种非嵌套且非原始的 JavaScript 数据类型。

// 浅对象的浅拷贝
let ShallowObj= { key1: 1, key2: 2, 
} 
let newObj = ShallowObj// 一个简单的重新分配为 newObj 创建共享内存
ShallowObj.key1 = 5
console.log(shallowObj) // {key1: 5, key2: 2} 
console.log(newObj) // {key1: 5, key2: 2}

当重新分配ShallowObj中key1的值时,会导致newObj中key1的值也随之发生改变。尽管这两个对象具有不同的变量名称,但它们实际上共享相同的内存空间。因此,如果需要更改shallowObj.key1的值,可以直接修改newObj.key1来获得相同的结果。这在某些情况下非常有用,例如当需要表示一组具有相同属性和值的特定对象时。然而,在运行时,可能需要给这些浅拷贝对象赋予不同的变量名称,以满足应用程序的需求,并作为不同的props传递给其他组件。通过使用不同的变量名称,可以根据不同的目标在应用程序中对它们进行独立操作,以实现所需的功能。

对浅对象进行深拷贝

//使用 Object.assign()
let myRadio = { podcasts: 19, albums: 378, playlists: 44 }
let deepCopyMyRadio = Object.assign( {}, myRadio )
deepCopyMyRadio.playlists = 62 // 只改变 deepCopyMyRadio
console.log(deepCopyMyRadio) // => { podcasts: 19, albums: 378, playlists: 62 }
console.log(myRadio)         // => { podcasts: 19, albums: 378, playlists: 44 }

ES6引入了一种新特性称为扩展运算符。扩展运算符用三个连续的点"…"表示,并可以在代码的多个地方使用。通常情况下,扩展运算符会为给定对象的每个顶级属性创建副本,并将它们扩展到新对象中。在特定情况下,可以选择使用浅拷贝或深拷贝来处理嵌套对象。在本例中,展示的是浅对象的深拷贝,因此可以使用Object.assign()方法或以下示例即可。

//用扩展运算符深拷贝
let myRadio = { podcasts: 9, albums: 38, playlists: 4 }
let copyMyRadio = { ...myRadio }
myRadio.albums = 88 // 还是只改变myRadio
console.log(myRadio) //=> { podcasts: 9, albums: 88, playlists: 4 }
console.log(copyMyRadio) //=> {podcasts: 9,albums: 38, playlists: 4}

不过这种写法的问题在于,随着项目规模和复杂性的增加,扩展运算符是一个有局限的解决方案。扩展运算符可以处理浅对象的深拷贝(非嵌套),即将一个对象的顶级属性复制到另一个对象中。然而,当涉及嵌套对象或多层级结构时,扩展运算符会遇到限制。它只能复制对象的第一层属性,而无法递归地复制嵌套的对象。

​ (分配方式:someOtherVar = someVar)

下面我们来看一下展开运算符在处理嵌套对象的复杂性时,并不如预期。对于嵌套对象来说,扩展运算符只提供了第一层属性的深拷贝,而对于所有嵌套的数据来说,它们与原始数据共享内存空间,实际上进行的是浅拷贝。

Population.total 在 city 和shallowCity 中共享一个内存点。扩展运算符获取顶层数据并将其添加到单独的内存空间;因此,shallowCity 的 name 属性实际上已更改。

对深对象进行深拷[JSON.parse(JSON.stringify())]

为了解决嵌套对象的复杂性问题,下面向大家介绍如何在深对象中进行深拷贝。在 JavaScript 中,当需要复制嵌套对象或数组时,深拷贝变得非常重要。深拷贝是一种创建独立全新对象的方法,它递归地复制每个嵌套对象和数组,有效地避免了使用共享内存带来的修改问题。其中,最常用的深拷贝方法是使用JSON.parse(JSON.stringify(object))。该方法首先将原始对象序列化为 JSON 字符串,然后再解析字符串并创建一个新对象,以确保所有属性和嵌套对象都被复制到全新的对象中。当然,需要注意的是该方法存在一定的局限性,例如无法复制函数、正则表达式等非数据类型,并且在某些情况下可能会带来性能问题。因此,在实际应用中,我们必须根据具体情况选择适合的深拷贝方法,以取得效率和正确性的平衡。

​ (对深对象进行深拷贝)

总结

JavaScript中的浅拷贝复制对象是创建一个新对象,但嵌套对象仍然共享内存。而深拷贝则创建一个独立的全新对象,包括嵌套对象在内都被完全复制。浅拷贝常用方法有Object.assign()和扩展运算符,而深拷贝可以使用JSON.parse(JSON.stringify())或第三方库。深拷贝适用于修改副本且不影响原始对象的情况,但可能消耗更多资源和时间。了解这两种拷贝方式的差异和应用场景是编写健壮代码的关键。

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

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

相关文章

小波与傅里叶变换的对比(Python)

直接上代码,理论可以去知乎看。 #Import necessary libraries %matplotlib inline import numpy as np import matplotlib.pyplot as plt import seaborn as snsimport pywt from scipy.ndimage import gaussian_filter1d from scipy.signal import chirp import m…

基于 sftp 的 NAS (局域网文件存储服务器)

局域网 NAS (文件存储服务器) 的基本功能有: 能够存储文件, 同时能够通过多个设备访问 (上传/下载) 文件. 这些功能通过 sftp 可以实现. sftp 是基于 SSH 的文件传输协议, SSH 全程加密传输, 使用 公钥 认证 (不使用密码/口令), 能够提供很高的安全性. 上文说到, 在 LVM 和 bt…

谷粒商城-个人笔记(集群部署篇三)

前言 ​学习视频:​Java项目《谷粒商城》架构师级Java项目实战,对标阿里P6-P7,全网最强​学习文档: 谷粒商城-个人笔记(基础篇一)谷粒商城-个人笔记(基础篇二)谷粒商城-个人笔记(基础篇三)谷粒商城-个人笔记(高级篇一)谷粒商城-个…

古建筑倾斜在线监测系统:科技守护历史的创新实践

​ ​​在文化遗产保护的广阔领域中,古建筑的健康监测占据着举足轻重的地位。然而,传统的监测方法往往受限于布线复杂、安装难度大以及对古建筑本体可能造成的伤害等问题。近年来,一种新型的古建筑倾斜在线监测系统应运而生,它…

Halcon 模糊圆边的找圆案例

Halcon 模糊圆边的找圆案例 基本思路 1.将图像转成灰度图像 2.再观察要找到的区域的灰度值变化,找到前景与背景的具体数值。 3.根据找到的前景与背景的具体数值,增强图像对比度。(使图像变成黑白图片) 4.使用灰度直图工具进行阈值…

用Vue3和Plotly.js绘制交互式3D散点图

本文由ScriptEcho平台提供技术支持 项目地址:传送门 使用 Plotly.js 创建 2D 密度图 应用场景介绍 密度图是一种可视化数据分布的图表,它显示了数据点的密度在不同区域的变化情况。在许多科学和工程领域中,密度图被广泛用于探索和分析数据…

5G(NR) NTN 卫星组网架构

5G(NR) NTN 卫星组网架构 参考 3GPP TR 38.821 5G NTN 技术适用于高轨、低轨等多种星座部署场景,是实现星地网络融合发展的可行技术路线。5G NTN 网络分为用户段、空间段和地面段三部分。其中用户段由各种用户终端组成,包括手持、便携站、嵌入式终端、车…

git撤销/返回到某次提交(idea工具 + gitbush)

不多说废话,直接展示使用。 方法一:使用idea工具进行返回 准备某次过度提交 使用idea打开git log 找到要回去的版本 点击右键选到reset 模式选hard,强制回滚 这个时候本地代码已经回归你指定的版本了。 这个时候再进行强制推送&#xff0c…

Drools开源业务规则引擎(三)- 事件模型(Event Model)

文章目录 Drools开源业务规则引擎(三)- 事件模型(Event Model)1.org.kie.api.event2.RuleRuntimeEventManager3.RuleRuntimeEventListener接口说明示例规则文件规则执行日志输出 4.AgentaEventListener接口说明示例监听器实现类My…

09 docker 安装tomcat 详解

目录 一、安装tomcat 1. tomcat镜像的获取 2. docker创建容器实列 3. 访问测试 404错误 4. 解决方案 5. 使用免修改版容器镜像 5.1. 运行实列的创建 5.2. 出现问题及解决: 6. 验证 OK 一、安装tomcat 1. tomcat镜像的获取 docker search tomcat #docker …

SCI二区TOP|蜘蛛黄蜂优化算法(SWO)原理及实现【免费获取Matlab代码】

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年,M Abdel-Basset受到蜘蛛黄蜂优化社会行为启发,提出了蜘蛛黄蜂优化算法(Spider Wasp Optimizer, SWO)。 2.算法原理 2.1算法思想 S…

视频监控技术在食品安全监管中的关键应用

视频监控技术在食品安全监管中的关键应用 1、视频监控技术在食品安全监管中的作用 在食品安全监管中,视频监控技术发挥着不可替代的作用。通过安装视频监控系统,可以实现对食品生产、运输、储存等各个环节的实时监控和录像存储。这不仅有助于监管部门及…

Linux的前世今生

Unix的起源和发展 1969年,AT&T贝尔实验室的Ken Thompson和Dennis Ritchie等人开发了Unix操作系统。Unix的设计理念强调小而简洁的工具,文本流和系统模块化,这些理念后来成为Linux开发的重要基础。1973年,Unix用C语言重新编写…

深度学习-数学基础(四)

深度学习数学基础 数学基础线性代数-标量和向量线性代数-向量运算向量加和向量内积向量夹角余弦值 线性代数-矩阵矩阵加法矩阵乘法矩阵点乘矩阵计算的其他内容 人工智能-矩阵的操作矩阵转置(transpose)矩阵与向量的转化 线性代数-张量(tensor…

卷技术还是卷应用?李彦宏给出了明确答案

如何理解李彦宏说的“不要卷模型,要卷应用” 引言 7月4日,2024世界人工智能大会在上海世博中心召开。百度创始人兼CEO李彦宏在产业发展主论坛上呼吁:“大家不要卷模型,要卷应用!”这句话引起了广泛讨论。李彦宏认为&a…

Python股票计算小程序(字符串格式化练习)

要求:打印的第一行使用f控制,第二行打印使用占位符,股价输出保留两位小数。 # 股价计算小程序 name"周氏集团" stock_price19.99 stock_code "9283" stock_price_daily_growth_factor1.2 growth_days7print(f"公司…

【Python进阶】继承进阶和私有权限

目录 一、继承进阶 1、方法重写 2、调用父类方法 3、多层继承 二、私有权限 1、私有属性 2、私有方法 面向对象基础:小白也能看懂的Python基础教程(8)-CSDN博客 一、继承进阶 1、方法重写 当父类的同名方法达不到子类的要求&#x…

Monaco 中添加 CodeLens

CodeLens 会在指定代码行上添加一行可点击的文字,点击时可以触发定义的命令,效果如下: 通过调用 API 注册 LensProvider,点击时触发 Command,首先要注册命令,通过 editor.addCommand () 方法进行注册。三个…

7月9日学习打卡-回文链表,交叉链表

大家好呀,本博客目的在于记录暑假学习打卡,后续会整理成一个专栏,主要打算在暑假学习完数据结构,因此会发一些相关的数据结构实现的博客和一些刷的题,个人学习使用,也希望大家多多支持,有不足之…

【微信小程序开发实战项目】——个人中心页面的制作

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…