js的深拷貝與淺拷貝

2021-09-24 18:57:05 字數 1494 閱讀 9443

前言:在說拷貝之前,先說說js中的資料儲存,我們知道js這廣義上資料型別分為兩種,原始資料型別和引用資料型別,原始資料型別包括string,boolean,number,null,undefined,symbol,引用型別有function,array,object,date,regexp等等其實這些都可以歸總為object型別。

對於原始型別資料,賦值即是拷貝,因為原始型別棧裡存的就是其值。對於複雜型別來說,變數儲存的是物件在堆空間裡的位址值,如果進行賦值,賦值僅僅是將其位址值給另乙個變數,實際上這兩個變數都指向同一位址。

//原始型別賦值,a,b的值相互不影響

let a = 23

let b = a

//複雜型別,當d的name改變,c的name改變,因為它們指向的就是同一物件

let c =

let d = c

現在,我們知道了拷貝就是為了生成兩份互相不影響的資料,同時我們知道原始型別的賦值即拷貝,而物件的屬性可能由原始資料型別組成,也有可能由物件型別組成,所以我們分類考慮。

var obj = 

//1、賦值操作

var obj2 = obj

//2、拷貝

var obj3 = {}

for(let key in obj)

如上,第二個我們簡單實現了拷貝。不過稍微思考一下,我們會發現,如果obj的屬性也是乙個複雜型別呢?

var obj = ,

age:23

}var obj2 = {}

for(let key in obj)

obj2.o.name = "張三"

obj.o.name //張三

如上**,按照開始的方法我們進行拷貝,拷貝後,我們發現obj.o與obj2.o指向的還是同一物件。如果我們需要完全拷貝,就得對obj.o也進行遍歷。

得出結論

1、淺拷貝:淺拷貝是會將物件的每個屬性進行依次複製,但是當物件的屬性值是引用型別時,實質複製的是其引用,當引用指向的值改變時也會跟著變化。(es6的object.assign方法就是進行淺拷貝)

2、深拷貝:深拷貝複製變數值,對於非基本型別的變數,則遞迴至基本型別變數後,再複製。 深拷貝後的物件與原來的物件是完全隔離的,互不影響,對乙個物件的修改並不會影響另乙個物件。

3、實現深拷貝

function deepcopy(o) 

} return c

}

優化,上面的深拷貝還有一點問題,如果出現迴圈引用,將會陷入死遞迴,導致程式崩潰。

function deepcopy(o,map = new weakmap()) 

let c = new o.constructor()

map.set(o,c)

for(let key in o)

} return c

}

js深拷貝與淺拷貝

1 基礎知識 基本型別與引用型別 js中可以把變數分成兩部分,基本型別和引用型別。基本型別包括 undefined null boolean number和string 引用型別值可能由多個值構成的物件。在對基礎型別資料進行拷貝時,實際相當於建立新的相同資料 hello 賦值給b var a hel...

js 淺拷貝與深拷貝

js 有兩種資料型別,基礎資料型別和引用資料型別 基礎資料型別都是按值訪問的,我們可以直接操作儲存在變數中的實際的值。而引用型別如array,1.淺拷貝 只複製指向某個物件的指標,而不複製物件本身,新舊物件共享一塊記憶體 淺拷貝是指只複製一層物件,當物件的屬性是引用型別時,實質複製的是其引用,當引用...

js深拷貝與淺拷貝

實現乙個頁面或者乙個功能時,常常遇到的場景需要我們備份乙個陣列或者物件,這時候出現了深拷貝與淺拷貝效果截然不同呀總結如下 var arr 1,2,3,4 shallowarr arr arr 0 change console.log arr console.log shallowarr change...