不要問我心裡有沒有你,我餘光中都是你。——餘光中
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yM0UzNhJmNiVGOmhjM2cjYiRTZlFTO1IWMxczNhVjNm9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
概念補漏
1. 堆棧的概念
在計算機中,堆棧是兩種資料結構。
- 棧(stack):先進後出;動态配置設定的空間 一般由程式員配置設定釋放, 若程式員不釋放,程式結束時可能由OS回收,配置設定方式倒是類似于連結清單。
- 堆(heap):隊列優先,先進先出;由作業系統自動配置設定釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于資料結構中的棧。
2.基本,引用資料類型
- 7種基本資料類型: Undefined、Null、Boolean、Number、String、Symbol(es6新增)、BigInt(es10新增), 基本資料類型都存儲在棧中,每種資料類型的記憶體空間大小是确定的,是以便于及時回收,更加容易管理記憶體空間。
- 1種引用資料類型: Object 。這其中包含了 object、array、function、date等等,這樣的資料存儲于堆中。但是其引用類型的資料存儲在棧記憶體中,如果需要通路可以通過先擷取到對象的指針位址,然後通過指針位址通路堆中的對應資料。
JavaScript不支援任何建立自定義類型的機制,而所有值最終都将是以上 8 種資料類型之一(排除之後新增)。
- 為了便于了解我做了一個示範。
clone是深拷貝還是淺拷貝_手寫系列——JS深拷貝和淺拷貝 - 堆棧圖
clone是深拷貝還是淺拷貝_手寫系列——JS深拷貝和淺拷貝
3.淺拷貝和深拷貝
淺拷貝:簡單的說淺拷貝就是隻進行一層的拷貝,對對象的屬性第一層進行拷貝,不管之後的層級。
深拷貝:對對象的屬性無限層級的拷貝。
代碼示範
這是我覺得現在比較好的深淺拷貝方式,随着語言的發展,之後類型的增多,會有一定的增删。
- 淺拷貝
// shallowCopyconst isObject = (o) => typeof o === 'object' && o !== null;const shallowCopy = (obj) => { if (!isObject(obj)) return obj; const res = Array.isArray(obj) ? [] : {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { const element = obj[key]; res[key] = element; } } return res;};
- 深拷貝
// deepCopyconst isObject = (o) => typeof o === 'object' && o !== null;const deepCopy = (obj, weakmap = new WeakMap()) => { if (!isObject(obj)) return obj; // 解決循環引用, 防止無限周遊 if (weakmap.get(obj)) return weakmap.get(obj); // 建立新對象存入weakmap const target = Array.isArray(obj) ? [] : {}; weakmap.set(obj, target); // symbol拷貝 const symArr = Object.getOwnPropertySymbols(obj); symArr.forEach((key) => { if (isObject(obj[key])) { target[key] = deepCopy(obj[key], weakmap); } else target[key] = obj[key]; }); // 對象的key for (const key in obj) { if (obj.hasOwnProperty(key)) { if (isObject(obj[key])) { target[key] = deepCopy(obj[key], weakmap); } else target[key] = obj[key]; } } return target;};
參考文檔
WeakMap MDN文檔