深入淺出理解 深拷貝 淺拷貝

2022-06-30 16:54:21 字數 1550 閱讀 4820

百科定義:拷貝就是拷貝指向物件的指標,意思就是說:拷貝出來的目標物件的指標和源物件的指標指向的記憶體空間是同一塊空間,淺拷貝只是一種簡單的拷貝,讓幾個物件公用乙個記憶體,然而當記憶體銷毀的時候,指向這個記憶體空間的所有指標需要重新定義,不然會造成指標錯誤。

. 基本型別:undefined,null,boolean,string,number,symbol

. 引用型別:object,array,date,function,regexp等

. 基本型別:基本型別值在記憶體中佔據固定大小,儲存在棧記憶體中(不包含閉包中的變數)

. 引用型別:引用型別的值是物件,儲存在堆記憶體中。而棧記憶體儲存的是物件的變數識別符號以及物件在堆記憶體中的儲存位址(引用),引用資料型別在棧中儲存了指標,該指標指向堆中該實體的起始位址。當直譯器尋找引用值時,會首先檢索其在棧中的位址,取得位址後從堆中獲得實體。

閉包中的變數並不儲存在棧記憶體中,而是儲存在堆記憶體中。這一點比較好想,如果閉包中的變數儲存在了棧記憶體中,隨著外層中的函式從呼叫棧中銷毀,變數肯定也會被銷毀,但是如果儲存在了堆記憶體中,記憶體函式仍能訪問外層已銷毀函式中的變數。看一段對應**理解下:

function a() 

return b

}

結論:在棧記憶體中的資料發生資料變化的時候,系統會自動為新的變數分配乙個新的之值在棧記憶體中,兩個變數相互獨立,互不影響的。

看一段**

let a = 

let b = a;

b.x = '程式設計師成長指北';

console.log(a.x); // 程式設計師成長指北

引用型別的複製,同樣為新的變數b分配乙個新的值,報錯在棧記憶體中,不同的是這個變數對應的具體值不在棧中,棧中只是乙個位址指標。兩個變數位址指標相同,指向堆記憶體中的物件,因此b.x發生改變的時候,a.x也發生了改變。

var a = [ 1, 3, 5,  ];

var b = array.prototype.slice.call(a);

b[0] = 2;

console.log(a); // [ 1, 3, 5, ];

console.log(b); // [ 2, 3, 5, ];

從輸出結果可以看出,淺拷貝後,陣列a[0]並不會隨著b[0]改變而改變,說明a和b在棧記憶體中引用位址並不相同。

淺拷貝定義:

通過這個官方的slice淺拷貝函式分析淺拷貝定義:

新的物件複製已有物件中非物件屬性的值和物件屬性的引用。如果這種說法不理解換一種乙個新的物件直接拷貝已存在的物件的物件屬性的引用,即淺拷貝。
說了賦值操作和淺拷貝操作,大家是不是已經能想到什麼是深拷貝了,下面直接說深拷貝的定義。

深拷貝會另外拷貝乙份乙個一模一樣的物件,從堆記憶體中開闢乙個新的區域存放新物件,新物件跟原物件不共享記憶體,修改新物件不會改到原物件。

深入理解深拷貝與淺拷貝

深拷貝和淺拷貝是經常在面試中會出現的,主要考察你對基本型別和引用型別的理解深度。我在無數次的面試中,應聘者還沒有乙個人能把這個問題回答情況,包括很多機構的培訓老師。這篇文章會讓你把基本型別和引用型別的區別搞得清清楚楚,搞清楚這兩者的區別,你對任何程式語言的都不怕,因為,這不是js一門語言,是任何程式...

淺拷貝,深拷貝的理解

淺拷貝 淺拷貝是將物件的每個屬性進行依次複製,當物件的屬性值是引用型別,實質複製的是其引用,指向的值改也會跟著變化,淺拷貝只拷貝一層 深拷貝 深拷貝複製變數值,對於非基本型別的變數,則遞迴至基本型別變數後,在複製,深拷貝後的物件與原來的物件是完全隔離的,互不影響,深拷貝是層層拷貝 淺拷貝 操作 簡單...

理解「淺拷貝」和「深拷貝」

淺拷貝 將原物件 原陣列 的 引用 直接賦給新物件 新陣列 新物件 新陣列 是原物件 原陣列 的乙個引用。如果改變這個新物件 新陣列 原物件 原陣列 就會改變。深拷貝 將原物件的各項屬性的 值 陣列的所有元素 都拷貝給新物件 新陣列 是拷貝的 值 而不是 引用 為什麼要使用深拷貝?希望改變新物件 新...