为什么要用深浅拷贝、什么是深浅拷贝、以及如何实现

简介: 首先我们要明白一点,js中数据类型分为:基本数据类型 (Number, String, Boolean, Null, Undefined, Symbol)对象数据类型 ( Object )**引用数据类型的值是保存在栈内存和堆内存中的对象。栈区内存保存变量标识符和指向堆内存中该对象的指针。当寻找引用值时,解释器会先寻找栈中的地址。然后根据地址找到堆内存的实体

👦个人简介:张清悠,字澄澈,号寻梦客,爱好旅行、运动,主攻前端方向技术研发,副攻Unity 3D、C++、Python人工智能等
📝个人寄语:学会不为过程的缓慢而焦虑,即使暂时未能如你所愿,但只要你在努力,你就在不断成长!
🙏个人公众号:清悠小猿(海量源码尽在其中,欢迎关注)

一、深拷贝和浅拷贝

首先我们要明白一点,js中数据类型分为:

基本数据类型 (Number, String, Boolean, Null, Undefined, Symbol)
对象数据类型 ( Object )

引用数据类型的值是保存在栈内存和堆内存中的对象。栈区内存保存变量标识符和指向堆内存中该对象的指针。当寻找引用值时,解释器会先寻找栈中的地址。然后根据地址找到堆内存的实体。
在这里插入图片描述

二、为什么要进行深浅拷贝

首先看下如下代码
let a = b = 2
a = 3
console.log(a)
console.log(b)
let c = d = [1,2,3]
let e = f = {
   
   a:1,b:2,c:3}
c[0] = 2
e.a = 2
console.log(d[0])
console.log(f.a)

会发现,同一个Array或者Object赋值给两个不同变量时,变量指向的是同一个内存地址,所以就会造成其中一个变量改变属性值,同时改变了另外一个变量的对应属性值。

而大多数实际项目中,我们想要的结果是两个变量(初始值相同)互不影响。所以就要使用到拷贝(分为深浅两种)

三、深浅拷贝的区别:

浅拷贝是将原始对象中的数据型字段拷贝到新对象中去,将引用型字段的“引用”复制到新对象中去,不把“引用的对象”复制进去,所以原始对象和新对象引用同一对象,新对象中的引用型字段发生变化会导致原始对象中的对应字段也发生变化。
深拷贝是在引用方面不同,深拷贝就是创建一个新的和原始字段的内容相同的字段,是两个一样大的数据段,所以两者的引用是不同的,之后的新对象中的引用型字段发生改变,不会引起原始对象中的字段发生改变。
在这里插入图片描述
结果:

一次构造

两次析构
在这里插入图片描述
编译系统在我们自己没有自定义拷贝构造函数时,会在拷贝对象时候调用默认拷贝构造函数,进行浅拷贝,即对指针name拷贝后出现两个指针指向同一个内存块。所以析构时候就析构了两次,导致内存泄漏。
在这里插入图片描述
所以在对“含有指针成员的对象”进行拷贝时,必须要自己定义拷贝构造函数,使拷贝构造后的对象指针成员有自己的内存空间,即进行深拷贝,避免内存泄漏。
在这里插入图片描述
在这里插入图片描述
test.cpp
在这里插入图片描述
结果:

构造一次

拷贝构造一次

析构两次
在这里插入图片描述
在这里插入图片描述
综上所述,浅拷贝是只对指针进行拷贝,两个指针指向同一个内存块,深拷贝是对指针和指针指向的内容都进行拷贝,拷贝后的指针是指向不同内的指针。

深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。

深拷贝

深拷贝复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。 深拷贝后的对象与原来的对象是完全隔离的,互不影响,
对一个对象的修改并不会影响另一个对象。
浅拷贝

浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化。
可 以 使 用
for in 、
Object.assign 、
扩 展 运 算 符 …
Array.prototype.slice()、
Array.prototype.concat() 、递归等递归函数实现深拷贝

针对这一共性的深浅拷贝问题,我也是略施小计,进行了一点皮毛性的总结吧,希望能给大家带来一定地方帮助,那么我的总结也是有效果的。 欢迎各位大牛留言指点,共同进步。

目录
相关文章
|
7月前
|
JSON JavaScript 前端开发
怎么做深拷贝?
怎么做深拷贝?
|
7月前
|
编译器 C++ Python
【C/C++ 泡沫精选面试题02】深拷贝和浅拷贝之间的区别?
【C/C++ 泡沫精选面试题02】深拷贝和浅拷贝之间的区别?
122 1
|
6月前
|
存储 编译器 C++
C++进阶之路:何为拷贝构造函数,深入理解浅拷贝与深拷贝(类与对象_中篇)
C++进阶之路:何为拷贝构造函数,深入理解浅拷贝与深拷贝(类与对象_中篇)
57 0
|
7月前
|
C++
C++什么是深浅拷贝,深浅拷贝的区别?
C++什么是深浅拷贝,深浅拷贝的区别?
|
存储 JSON JavaScript
面试常问:深拷贝和浅拷贝
在了解深拷贝和浅拷贝之前我们先简单了解一下堆和栈的概念。 堆的概念:在javaScript中,堆是用来存储地址的。比如引用数据类型的地址就是存储在堆中。 栈的概念:栈在javascript中用于存储值的。比如基本数据类型都是直接存在栈内存中的。
|
存储 JSON 缓存
前端面试:浅拷贝和深拷贝的区别?
前端面试:浅拷贝和深拷贝的区别?
123 0
|
存储 JavaScript 数据处理
深浅拷贝问题
深浅拷贝问题
72 0
|
JSON JavaScript 前端开发
【面试官系列】请讲讲你知道的关于对象和数组深、浅拷贝的一些技巧 ~(一)
【面试官系列】请讲讲你知道的关于对象和数组深、浅拷贝的一些技巧 ~(一)
|
Web App开发 JSON JavaScript
【面试官系列】请讲讲你知道的关于对象和数组深、浅拷贝的一些技巧 ~(二)
【面试官系列】请讲讲你知道的关于对象和数组深、浅拷贝的一些技巧 ~(二)