JS深拷貝與淺拷貝

2021-09-28 20:33:08 字數 2325 閱讀 4244

如何區分深拷貝與淺拷貝,簡單點來說,就是假設b複製了a,當修改a時,看b是否會發生變化

①如果b也跟著變了,說明這是淺拷貝,功力不夠

②如果b沒變,那就是深拷貝,自食其力,修成正果

資料型別

基本資料型別:

number,string,boolean,null,undefined

引用資料型別:

array,object,函式

資料儲存

基本型別–名值儲存在棧記憶體

記憶體中,例如let a=1;

當b=a複製時,棧記憶體會新開闢乙個記憶體,例如這樣:

所以此時修改a=2,對b並不會造成影響,因為此時的b已自食其力,不受a的影響了

當然,let a=1,b=a;雖然b不受a影響,但這也算不上深拷貝,因為深拷貝本身只針對較為複雜的object型別資料

引用資料型別

名存在棧記憶體中,值存在於堆記憶體中,但是棧記憶體會提供乙個引用的位址指向堆記憶體中的值

以上面淺拷貝的例子畫個圖

引用資料型別–概念圖

當a[0]=1時進行陣列修改時,由於a與b指向的是同乙個位址,所以自然b也受了影響,這就是所謂的淺拷貝了

要是在堆記憶體中也開闢乙個新的記憶體專門為b存放值,就像基本型別那樣,豈不就達到深拷貝的效果了

深拷貝

(1)slice()不帶任何引數,預設返回乙個長度和原陣列相同的新陣列

(2)concat()不帶任何引數,把返回陣列和乙個空陣列合併後返回,即返回乙個長度和原陣列相同的新陣列

(3)直接遍歷,新增到空陣列

(4)es2015,es6三點擴充套件運算子

將上述案例,簡單修改下,資料結構巢狀,做兩層巢狀

驗證後發現之前的幾種方法只能拷貝一級資料,那如何拷貝所有層級呢?

接下來介紹兩種常用的方案

①jquery的extend

②json的序列化和反序列化

(1)jq的extend方法

語法:$.extend( [deep ], target, object )

①deep表示是否深拷貝,為true為深拷貝,為false為淺拷貝

②target目標物件,其他物件的成員屬性將被附加到該物件

③object拷貝源物件

(2)json的序列化和反序列化

語法:json.parse(json.stringify(***x))

實現原理:先將物件轉為乙個基本資料型別,再執行拷貝

深拷貝和淺拷貝的區別

(1)淺拷貝: 將原物件或原陣列的引用直接賦給新物件,新陣列,新物件/陣列只是原物件的乙個引用

(2)深拷貝: 建立乙個新的物件和陣列,將原物件的各項屬性的「值」(陣列的所有元素)拷貝過來,是「值」而不是「引用」

深拷貝相關

(1)為什麼要使用深拷貝?

希望在改變新的陣列(物件)的時候,不改變原陣列(物件)

(2)怎麼檢驗深拷貝成功?

改變任意乙個新物件/陣列中的屬性/元素, 都不改變原物件/陣列

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...