本文主要講一下 js 的基本資料類型以及一些堆和棧的知識和什麼是深拷貝、什麼是淺拷貝、深拷貝與淺拷貝的差別,以及怎麼進行深拷貝和怎麼進行淺拷貝。
堆和棧的差別
其實深拷貝和淺拷貝的主要差別就是其在記憶體中的存儲類型不同。
堆和棧都是記憶體中劃分出來用來存儲的區域。
在将深拷貝和淺拷貝之前,我們先來重新回顧一下 ECMAScript 中的資料類型。主要分為
基本資料類型主要是:
undefined,boolean,number,string,null
。 基本資料類型值不可變 基本資料類型存放在棧中 基本類型的比較是值的比較 基本類型的指派的兩個變量是兩個獨立互相不影響的變量。 引用類型( object
)是存放在堆記憶體中的,引用類型值可變 引用類型的比較是引用的比較(對象在堆記憶體的引用位址)
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);