一、基本数据类型和引用数据类型的存储方式
在理解浅拷贝和深拷贝之前,简单理解一下不同数据类型的存储方式。
基本数据类型是存储在栈中,栈中存放对应的值。
引用数据类型地址存储在栈中,数据存在堆中。
var age=21;
let arr = ["小明", "小王"];
比如上述代码中,先定义两个局部变量:
这里给age赋值时数字21,是基本数据类型。基本数据类型是存储在栈中的,所以值21存放在栈中。
由于arr是数组,是引用数据类型,所以在栈中申请空间存放arr数组的地址(该地址指向堆中),堆中存放数组的数据。
对于这个问题理清楚,那么对于深浅拷贝的区别会更好记住
浅拷贝:只拷贝了存储地址。
深拷贝:拷贝了数据内容。
深浅拷贝仅限于引用数据类型。
这里先简单总结以下,下面展开说。
二、深拷贝和浅拷贝
1、浅拷贝
浅拷贝就是拷贝值到新的数组或者对象中,只拷贝第一层的数据,也就是值拷贝或者是地址的拷贝(常用assign方法)
以下有三种方法,第一种方便理解,后面两种书写比较简单,assign也是比较常用。
当对象或者数组里面存在对象或者数组,也就是说嵌套了,那么拷贝过去的就不是值,而是地址了。
比如,下面的代码中,arr拷贝到brr中,其中brr[2] 是["小花"]这个数组存放的地址,并不是["小花"],所以当对arr[2]中添加小王,实际上也就是对小花这个数组添加小王。而brr[2]这个时候指向小花的地址,显示出阿来的就是小花和小王,brr也会跟着arr的操作而改变。
那么,这种情况,我们就需要使用深拷贝
2、深拷贝
深拷贝有两种实现方式。第一种是JSON实现,也就是反序列化;第二种就是递归。JSON是比较简单也比较好理解的。递归相比起来比较复杂。
(1)JSON
JS对象转换成字符串:JSON.stringfy()
字符串转换成JS对象: JSON.parse ()
我们举简单的例子:如果是对象、数组等,直接赋值,那么赋值的就是地址,这就导致了一个改变,另一个也会改变。
如果使用JSON深拷贝:因为JSON取出来的是只是单纯的数据, 而不是地址; 然后再将JSON的数据格式转换成js, { }有在堆中开空间的作用, 所以原数据不会发生改变。
(2)递归方式
b站上面有一个视频讲解很容易理解,推荐:JS_浅拷贝_深拷贝_哔哩哔哩_bilibili