1、數據類型
首先我們先了解一下JavaScript中的數據類型,這有利於我們理解深淺拷貝的問題:
1、基本數據類型(undefined、boolean、number、string,null)
存放在棧中,數據大小確定,內存空間大小可以分配,是直接按值存放的,可以直接訪問。
基本數據類型的值是不可變的,動態修改了基本數據類型的值,它的原始值也是不會改變的。
2、引用類型(object)
存放在堆中,變量實際上是一個存放在棧內存的指針,這個指針指向堆內存中的地址。每個空間大小不一樣,要根據情況開進行特定的分配。值是可變的。
3、傳值 vs 傳址(地址)
我們注意到,基本數據的賦值操作等同於新開辟一段棧內存,新的變量與原來變量是互相獨立不影響的;而引用類型的賦值是傳址。只是改變指針的指向而已(還是共用一塊內存),兩個變量指向同一對象,會互相影響。這就是我們接下來要探討的深淺拷貝的由來。
2、淺拷貝
那什么是淺拷貝呢? 只復制一層對象的屬性,並不包括子對象的數據。
怎么解釋這句話呢?我們對一個對象進行淺拷貝時,生成一個新的變量,第一層對象的屬性是新開辟棧內存的,跟原變量的值互相獨立不影響。但是:子對象的值是引用原變量的值的,也就是跟它共用內存,所以現變量子對象內的值改變會影響到原變量的值。
實現淺拷貝的方法:
淺拷貝 vs 賦值
賦值是引用原對象的值,不管是第一層屬性還是子對象的值,一旦發生改變就會影響到原對象的值。但顯然淺拷貝不是這樣的,所以賦值是賦值,淺拷貝是淺拷貝。
3、深拷貝
什么是深拷貝?復制原對象的所有屬性,包括子對象的數據。
說完淺拷貝,對深拷貝不言自明。深拷貝是對對象以及對象的所有子對象進行拷貝。
那怎么實現深拷貝呢?我們可以使用遞歸的方法去寫:
其實之前已經提到過了,詳見:https://www.cnblogs.com/hxw1024/p/12051562.html
![]()




