浅拷贝和深拷贝(图文详解)

news/2024/10/17 13:27:09/

        前端面试中,面试官经常会提到关于浅拷贝和深拷贝的问题。但是我总是理解于它的表面,面试中再深挖一点就会卡壳,我想把我的理解写下来,希望可以帮助到大家,如果有错误的地方希望大家可以指正,以免误导~

看这篇文章之前,对于赋值的过程大家不了解的可以看我的这一篇文章https://blog.csdn.net/jisuaijicainiao/article/details/140844128?spm=1001.2014.3001.5501

浅拷贝的过程直接举例子说明能更加直观理解

首先说明一下浅拷贝的过程: 浅拷贝会创建一个新对象,并将原始对象的属性逐个复制到这个新对象中。然而,对于引用类型的属性(如对象、数组),浅拷贝只会复制引用,而不是复制引用类型的内容。

let obj1 = {'name':'Lili','school':{'address':"北京"}
}
let obj2 = Object.assign({},obj1)
obj2.name = 'sasa'
obj2.school.address = '上海'
console.log(obj1.name)  //'Lili'
console.log(obj1.school.address)  //'上海'

       上面代码的过程通过图片显示就如下,在未改变obj2任何值之前,内存分配中做了这些操作。浅拷贝就是重新创建了一个对象,把被拷贝对象的属性值都放进了自己的对象中。对于引用类型,值也只是存储了引用地址。

       在改变obj2的属性值之后,如下图所示。因为obj2是在一个新的对象中,所以它的基本类型属性的修改不会影响到obj1。但是对于school属性,它是引用类型存储的是一个对象的地址,它跟obj1的school指向的是相同的一个对象。所以修改obj2就会影响到obj1的值。

 但是还有一种情况就是以下代码

let obj1 = {'name':'Lili','school':{'address':"北京"}
}
let obj2 = Object.assign({},obj1)
obj2.name = 'sasa'
obj2.school = {address:'上海'}
console.log(obj1.name)  //'Lili'
console.log(obj1.school.address)  //'北京'

 图解的话就是下图这样的,obj2修改school属性的值,相当于重新创建了一个对象,在堆内存中重新开辟了一块空间,obj2对象的school属性指向新的对象地址。所以obj1和obj2此时不指向同一块空间,所以并不影响obj1对象。

        浅拷贝的实现方式除了Object.assign()方法【let obj2 = Object.assign({}, obj1)】,还有扩展运算符‘...’【let obj2 = {...obj1}】,还有Array.prototype.slice()通常用于数组拷贝【let arr2 = arr1.slice()】,还有Array.prototype.concat()用于数组拷贝【let arr2 = arr1.concat()】等等。

深拷贝

深拷贝的过程:深拷贝会递归的遍历对象的每个属性,如果属性是基本类型就会直接复制值,如果属性是引用类型,深拷贝就会创建一个新的对象或数组,并递归的复制其中的所有属性。深拷贝后的对象与原对象在内存上是完全独立的。

举例说明

let obj1 = {name:'Lili',school:{address:"北京"}
}
let obj2 = JSON.parse(JSON.stringify(obj1))obj2.name = 'sasa'
obj2.school.address = '上海'
console.log(obj1.name)  //'Lili'
console.log(obj1.school.address)  //'北京'

上面代码的图解过程,根据上述深拷贝的过程,在修改拷贝对象的值之前我们可以得到下图的结果。obj1和obj2是两个完全独立的对象。

        当我们对obj2的属性值进行修改后,如下图所示。obj1是完全不受影响的,无论你怎么修改obj2的值都不会改变obj1的值。

 实现深拷贝的方法除了JSON.pares(JSON.stringify())外【let obj2 = JSON.pares(JSON.stringify())】,还有递归遍历手动复制实现,还可用lodash库的_.cloneDeep()方法【let obj2 = _.cloneDeep(obj1)】

今天就到这里吧~ 继续加油


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

相关文章

Android 自适应屏幕技术

layout自适应屏幕大小Android手机屏幕大小不一,有480x320,640x360,800x480.怎样才能让App自动适应不同的屏幕呢? 其实很简单,只需要在res目录下创建不同的layout文件夹,比如:layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据…

论文浅尝 | 超越实体对齐: 通过实体关系协同实现完整的知识图谱对齐

笔记整理:米尔扎提阿力木,天津大学硕士,研究方向为大模型 论文链接:https://arxiv.org/abs/2407.17745 摘要 知识图谱对齐(Knowledge Graph Alignment, KGA)旨在整合来自多个来源的知识,以解决单个知识图谱在覆盖范围和…

【设计模式】策略模式和代理模式

策略模式 策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来&#xf…

模板之家 mymoban

模板之家mymoban.com 是一个提供各种网站模板资源的平台,涵盖了多种类型的模板,包括网页模板、PPT模板、Word模板、Excel模板等。此外,该网站还提供免费下载服务,用户可以下载到网站模板、小程序模板、JS特效、前端代码以及建站教…

kafka的一个有趣问题(BUG)

这是我的第104篇原创文章 问题由来 在使用kafka时,创建topic,对某个topic进行扩分区的操作,想必大家肯定都使用过。尤其是集群进行扩容时,对流量较大的topic进行扩分区操作。一般而言,期望的效果是:新扩的分…

数学建模学习(115):主成分分析(PCA)与Python实践

文章目录 一.主成分分析简介1.1 数学背景与维度诅咒1.2 PCA的定义与应用二.协方差矩阵——特征值和特征向量三.如何为数据集选择主成分数量四.特征提取方法五.LDA——与PCA的区别六.PCA的应用七.PCA在异常检测中的应用八.总结一.主成分分析简介 1.1 数学背景与维度诅咒 主成成…

C语言 之 字符相关函数

文章目录 字符分类函数字符转换函数 本章内容主要讲的是c语言中的字符相关的一些函数的作用用法和使用 为了方便我们对字符的各种操作,C语⾔标准库中提供了⼀系列库函数,我们大概可以根据其功能分成两类函数 字符分类函数 C语言中有一系列函数是专门用…

QT:Qt与ECharts

介绍ECharts ECharts是一款基于JavaScript的数据可视化图表库,由百度团队最初开发,并在2018年初捐赠给Apache基金会,成为ASF孵化级项目。随着项目的不断发展,ECharts在2021年1月26日正式毕业,成为Apache顶级项目 链接…