## 堆與棧
>[success] 堆是動態分配內存,內存大小不一,也不會自動釋放。
> 棧是自動分配相對固定大小的內存空間,并由系統自動釋放。
### 區別
棧
* 自動分配內存空間,會自動釋放。存放基本數據類型的值,引用類型的地址,按值訪問,先進后出
* 動態分配的空間一般由程序員分配釋放, 若程序員不釋放,程序結束時由系統回收
堆
* 動態分配的內存,大小不定,不會自動釋放。隊列優先,先進先出
* 存放引用數據類型的對象值、函數的參數值,局部變量的值等
* 不允許直接訪問、操作堆內存值,引用類型訪問的是棧內存中的引用地址;操作對象值時實際上操作的是對象的引用。

### 傳值與傳址
由于基本類型直接存在在棧內存中,基本類型的使用時,直接獲取數據值。引用類型使用時先讀取棧中引用地址再讀取對應堆中數據值。
## 淺拷貝與深拷貝
淺拷貝
引用類型拷貝時,直接復制值,復制對象與原對象指向同一引用值,更改復制對象值即更改對象引用值,即更改原對象值。
~~~
const obj = { a: 10 };
const copy = obj;
copy.b = 20;
console.log("obj ", obj ); // { a: 10, b: 20 }
console.log("copy ", copy ); // { a: 10, b: 20 }
~~~
深拷貝
1. JSON.parse(JSON.stringify())
> 當有屬性值為 undifined 時 JSON.stringify() 方法會將移除該屬性
~~~
// JSON.parse(JSON.stringify())
const deepClone = JSON.parse(JSON.stringify(obj));
deepClone.c = 30;
console.log("obj", obj); // { a: 10, b: 20 }
console.log("deepClone", deepClone); // { a: 10, b: 20, c: 30 }
~~~
2. es6語法
~~~
const deepClone = {...obj};
deepClone.c = 30;
console.log("obj", obj); // { a: 10, b: 20 }
console.log("deepClone", deepClone); // { a: 10, b: 20, c: 30 }
~~~
3. deepClone
~~~
function deepClone(obj) {
let newObj;
if (Array.isArray(obj)) {
newObj = obj.map(key => deepClone(obj[key]));
} else if (Object.prototype.toString.call(obj) === "[object Object]") {
newObj = {};
for (const key in obj) {
newObj[key] = deepClone(obj[key]);
}
} else {
newObj = obj;
}
return newObj;
}
~~~
4. 引用第三方庫像 loadsh: https://www.lodashjs.com/docs/lodash.cloneDeep