用Windows文件夹演示JS复杂数据类型的深浅拷贝
前言
在逆战班对JavaScript学习了近10天后,我开始接触到JavaScript中一个比较重要的数据类型——数组。在学习数组的过程中,我接触了浅拷贝和深拷贝两个概念,为了便于自己和其他有需要的小白更容易理解深浅拷贝之间的关系,我打算用我们常用的Windows文件夹来模拟讲解一下深浅拷贝。
堆和栈的模拟
首先,我们需要明白:计算机的数据存储在堆内存(下文简称“堆”)和栈内存(下文简称“栈”)之中。(对于堆和栈不了解的朋友可以参考这位大牛的博客:https://blog.csdn.net/K346K346/article/details/80849966。)数据按照类型可以分为"基本数据类型"和"复杂数据类型",所谓基本数据类型,一般指布尔值、数值、字符串等;而复杂数据类型(下文称“引用数据类型”)则包括了对象、数组、函数等。这两种数据类型存储数据的方式有所不同,基本数据类型会将变量的名称和变量的值都存储在栈中,而复杂数据类型会将变量的名称存储在栈中,将变量的值存储在堆中。
基础数据的拷贝
对于基础数据类型的拷贝,如执行以下代码:
var a = 1;
var b = 2;
b = a;
这一过程可以用计算机模拟为:
1.在栈文件中新建a和b两个文本,在a文本中写入数字1,在b文本中写入数字2。
2.将a文本中的数字1复制,覆盖粘贴掉b文本中的数字2。
此时,a和b分别独立,修改a或b中的内容,不会对另一个文本造成影响。
引用数据的浅拷贝
通过赋值操作对引用数据类型进行拷贝时,代码如下:
var a = [1,2];
var b = [3,4];
b = a;
该操作看似与基础数据类型的拷贝相同,而实际原理却是完全不同的,我将通过以下计算机操作来模拟这一过程。
1.在堆文件下创建名为地址a的文本,在其中写入[1,2]。
2.在栈文件夹下创建一个快捷方式,键入对象位置中填写堆中地址a的路径,并为快捷方式命名为a。
3.对b进行同样的操作,由此我们得到了两个快捷方式和两个文本
注:双击快捷方式会打开对应地址的文本,这一过程可用于模拟调用复杂数据类型。
4.将a赋值给b,并不会改变“地址b”中的内容,而是改变快捷方式b中所存储的内存地址。
5.再次双击快捷方式b,打开的不再是“地址B”,而是“地址A”。
这样直接将一个引用数据类型的地址赋值给另一个变量存储的操作称为浅拷贝,当对b执行操作(如添加删除数据)时,将会改变地址a中的值,从而a也将受到影响。
引用数据的深拷贝
怎样才能实现既将a中的数据拷贝到b中,又使二者独立而互不影响呢?为此我们可以使用遍历,将地址a中的数值逐一复制到地址b中,这一过程的代码如下。
var a = [1,2];
var b = [3,4];
b.splice(0); //清空地址b中的数据
a.forEach(function(val,key,arr){
b[key] = val;
})
而这一操作,就是直接用地址a中的内容覆盖地址b,最终效果也就是a和b仍旧是分别存储不同的内存地址,但是a中的数据拷贝到了b中。对这两个变量做任何操作,都不会影响另一个变量。而这种只复制引用数据类型中的数值而不复制地址的操作称为深拷贝。以上就是我个人对于复杂数据类型深浅拷贝的一些个人简介了,如果有问题欢迎读者友善地指出,也希望我的文章能对你有所帮助。