天天看點

深拷貝與淺拷貝的深度了解

本文主要講一下 js 的基本資料類型以及一些堆和棧的知識和什麼是深拷貝、什麼是淺拷貝、深拷貝與淺拷貝的差別,以及怎麼進行深拷貝和怎麼進行淺拷貝。

堆和棧的差別

其實深拷貝和淺拷貝的主要差別就是其在記憶體中的存儲類型不同。

堆和棧都是記憶體中劃分出來用來存儲的區域。

在将深拷貝和淺拷貝之前,我們先來重新回顧一下 ECMAScript 中的資料類型。主要分為

基本資料類型主要是:

undefined,boolean,number,string,null

。    基本資料類型值不可變     基本資料類型存放在棧中  基本類型的比較是值的比較  基本類型的指派的兩個變量是兩個獨立互相不影響的變量。

引用類型(

object

)是存放在堆記憶體中的,引用類型值可變   引用類型的比較是引用的比較(對象在堆記憶體的引用位址)

淺拷貝 :隻複制一層對象的屬性    對于 簡單資料類型的資料 (直接複制)   是以拷貝前後沒有影響       對于複雜資料類型  由于隻拷貝了引用位址     是以複制後 對新對象進行修改 可  能會影響原對象

深拷貝   :開辟一個新的記憶體空間,存儲空新對象(與源對象無關),然後遞歸周遊源對象結構(直到源對象都為基本資料類型),然後進行給空對象的複制操作

深拷貝的代碼

1 // 舊對象
 2 let oldObj = {
 3   name: "張三",
 4   age: 18,
 5   sex: "男",
 6   hobbies: { weight: 175 },
 7   color: ["pink", "red", "blue"],
 8 };
 9 // 新對象
10 let newObj = {};
11 // 定義deepCopy函數
12 function deepCopy(newObj, oldObj) {
13   for (var key in oldObj) {
14     //   拿到屬性值
15     var item = oldObj[key];
16     // 判斷屬性值是不是數組  ---先判斷數組 再判斷對象
17     if (item instanceof Array) {
18       // 遞歸調用 周遊結構
19       newObj[key] = [];
20       deepCopy(newObj[key], item);
21     } else if (item instanceof Object) {
22       // 判斷屬性值是不是對象
23       newObj[key] = {};
24       deepCopy(newObj[key], item);
25     } else {
26       // 值類型為基本類型了  進行指派操作
27       newObj[key] = item;
28     }
29   }
30   //   傳回新的資料對象
31   return newObj;
32 }
33 // 調用深度拷貝函數
34 deepCopy(newObj, oldObj);
35 console.log(newObj);      
1 // 舊的對象
 2 let obj = {
 3   name: "zhangsan",
 4   age: 18,
 5   hobbies: {
 6     weight: 175,
 7   },
 8 };
 9 // 新的對象
10 let o = {};
11 
12 // es6文法糖 淺拷貝
13 let res = Object.assign(o, obj);
14 console.log(res);
15 
16 // for in可實作淺拷貝
17 for (var key in obj) {
18   // k是屬性名 obj[k] 屬性值
19   o[key] = obj[key];
20 }
21 
22 console.log(o);      

繼續閱讀