js深度拷貝與淺度拷貝

2021-09-28 20:26:58 字數 2107 閱讀 9522

如果你想真正自己理解和運用深度轉殖的話,首先必須要了解的就是js中的原始值和引用值,以及它們的儲存位置及方式。這裡簡單的說一下,原始值是儲存在棧裡的,而且儲存的是變數的實際值。引用值儲存在堆裡,且儲存的是乙個指標,該指標指向記憶體中的某個位置,該位置儲存變數的實際值。

var a =2;

var a_copy = a ;

a_copy =3;

console.

log(a)

;var arr =[1

,2,3

,4];

var arr_copy = arr ;

arr_copy.

push(5

);console.

log(arr)

;var obj =

;var obj_copy = obj ;

obj_copy.name =

'過客'

;console.

log(obj.name)

;

最終輸出結果如下:

可以看出當複製引用值(陣列、物件)時,修改複製後的變數,原來的變數也跟著變了,原因就是當引用值複製時複製的是指標,所以修改它們的變數時指標沒有改變,而是指標指向的值變了,所以指向同一指標的原變數也就變了,不過在有一種情況下,修改複製後的變數,被複製的變數不會跟著改變,那就是複製後,給複製變數重新定義值得時候,原來的變數不會受影響,因為此時已經給複製後的變數重新分配指標了。

var arr =[1

,2,3

,4];

var arr_copy = arr ;

arr_copy =[1

,2,3

,4,5

];console.

log(arr)

;console.

log(arr_copy)

;var obj =

;var obj_copy = obj ;

obj_copy =

;console.

log(obj.name)

;console.

log(obj_copy.name)

;

最終輸出結果如下:

對於乙個引用型別,如果直接將它賦值給另乙個變數,由於這兩個引用指向同乙個位址,這時改變其中任何乙個引用,另乙個都會受到影響。當我們想複製乙個物件並且切斷與這個物件的聯絡,就要使用深拷貝。

有點麻煩但是通用的方法prototype判斷變數的型別,由於函式具有不可遍歷性,所以儘管函式也是引用值,我們也可以按照淺度的方法複製即可。

var userinfo =

}function

gettype

(obj)

else

if(object.prototype.tostring.

call

(obj)

=='[object array]'

)else

}function

deepcopy

(obj)

else:[

];for(

var key in obj)}}

return newobj;

}var newinfo =

deepcopy

(userinfo)

;newinfo.name =

'過客。。。。'

;console.

log(newinfo)

;console.

log(userinfo)

;

最終結果輸出如下:

這裡用到.hasownproperty是為了避免在拷貝有繼承時拷貝到繼承自物件中的值(也就是a繼承b,使用.hasownproperty就是為了只拷貝a中的變數,過濾繼承自b中的變數。)

深度拷貝和淺度拷貝

文字說明 比如乙個陣列 array 淺度拷貝是當陣列a變數成陣列b的時候,b改變裡面的陣列數值的時候,a也隨著改變,深度拷貝是噹噹陣列a變數成陣列b的時候,b改變裡面的陣列數值的時候,a裡面的陣列陣列不隨著改變,那麼為什麼淺度拷貝會改變a的陣列值而深度拷貝則不會呢?因為淺度拷貝指向的是同乙個記憶體,...

js深度拷貝和淺度拷貝的深入理解

首先我們來說說什麼是拷貝 就是複製的同時加上了傳值。然後問題就來了什麼是有深度的什麼是淺度的,在想要了解我們這個問題之前我們先來了解一下下面的乙個知識點 基本型別傳遞,引用型別傳遞 首先我們來看下基本型別傳遞 就是基本資料型別之間的資料傳遞,什麼是基本資料型別呢?string,number,bool...

js深拷貝與淺拷貝

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