JS:对象的深浅拷贝
1、数据类型
首先我们先了解一下JavaScript中的数据类型,这有利于我们理解深浅拷贝的问题:
1、基本数据类型(undefined、boolean、number、string,null)
存放在栈中,数据大小确定,内存空间大小可以分配,是直接按值存放的,可以直接访问。
基本数据类型的值是不可变的,动态修改了基本数据类型的值,它的原始值也是不会改变的。
2、引用类型(object)
存放在堆中,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况开进行特定的分配。值是可变的。
3、传值 vs 传址(地址)
我们注意到,基本数据的赋值操作等同于新开辟一段栈内存,新的变量与原来变量是互相独立不影响的;而引用类型的赋值是传址。只是改变指针的指向而已(还是共用一块内存),两个变量指向同一对象,会互相影响。这就是我们接下来要探讨的深浅拷贝的由来。
2、浅拷贝
那什么是浅拷贝呢? 只复制一层对象的属性,并不包括子对象的数据。
怎么解释这句话呢?我们对一个对象进行浅拷贝时,生成一个新的变量,第一层对象的属性是新开辟栈内存的,跟原变量的值互相独立不影响。但是:子对象的值是引用原变量的值的,也就是跟它共用内存,所以现变量子对象内的值改变会影响到原变量的值。
实现浅拷贝的方法:
浅拷贝 vs 赋值
赋值是引用原对象的值,不管是第一层属性还是子对象的值,一旦发生改变就会影响到原对象的值。但显然浅拷贝不是这样的,所以赋值是赋值,浅拷贝是浅拷贝。
3、深拷贝
什么是深拷贝?复制原对象的所有属性,包括子对象的数据。
说完浅拷贝,对深拷贝不言自明。深拷贝是对对象以及对象的所有子对象进行拷贝。
那怎么实现深拷贝呢?我们可以使用递归的方法去写:
其实之前已经提到过了,详见:https://www.cnblogs.com/hxw1024/p/12051562.html