前言:在說拷貝之前,先說說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...