你真的瞭解資料在堆疊中的儲存方式嗎?
阿新 • • 發佈:2021-02-03
**JavaScript資料型別分為:**
分類 | 型別
-------- | -----
原始資料型別(7種) | Number、String、Boolean、Null、Undefined、Symbol、BigInt
引用資料型別 | Object
先看兩段程式碼
```javascript
let num = 1;
let data = num;
data = 2;
console.log('num : ' + num);//num : 1
```
```javascript
let obj = {
name : 'obj'
}
let data = obj;
data.name = 'data';
console.log('obj.name : ' + obj.name);//obj.name : data
```
**出現這種情況是由於JavaScript中原始資料型別和引用資料型別儲存的方式不同導致**
**這裡要引入兩個概念:棧和堆**
儲存方式 | 優點| 缺點
-------- | -----| -----
**棧(stack)** | 儲存大小固定,且具有後進先出的線性操作功能,便於對儲存中的資料進行操作| 儲存容量小
**堆(heap)** | 儲存容量大| 儲存大小不固定,在不知道記憶體地址時不易操作儲存中的資料
==注:這裡的優缺點只是相對而言==
**再看看**
分類 | 特點
-------- | -----
原始資料型別 | 需要記憶體大小固定
引用資料型別 | 需要記憶體大小不固定
**所以原始型別是儲存在棧中的**
```javascript
let num = 1;
let data = num;
data = 2;
console.log('num : ' + num);//num : 1
```
**具體流程如下:**
**1.在棧中開闢一塊記憶體並將值1儲存於其中,宣告變數num,使num指向新開闢的這塊記憶體地址;**
**2.在棧中再開闢一塊記憶體,將變數num指向的記憶體中的值複製到新開闢的記憶體中,宣告變數data,使data指向新開闢的這塊記憶體地址;**
**3.將變數data指向的記憶體中的值置換為2;**
**4.輸出變數num指向的記憶體中儲存的值。**
**如圖:**
![在這裡插入圖片描述](https://img2020.cnblogs.com/blog/1604228/202102/1604228-20210203142236093-2043483323.gif)
**引用資料型別的資料儲存在堆中 同時又把儲存在堆中的資料所處的地址值儲存到棧中**
```javascript
let obj = {
name : 'obj'
}
let data = obj;
data.name = 'data';
console.log('obj.name : ' + obj.name);//obj.name : data
```
**具體流程如下:**
**1.在堆中開闢一塊記憶體,將物件儲存於其中,再在棧中開闢一塊記憶體,將新開闢的記憶體的地址值儲存到棧中,宣告變數obj,使obj指向棧中新開闢的這塊地址值;**
**2.在棧中再開闢一塊記憶體,將obj指向的記憶體中的值複製到新開闢的記憶體中來,宣告變數data,使data指向新開闢的這塊記憶體地址;**
**3.通過變數data指向的棧記憶體中儲存的堆記憶體的地址值,修改堆中資料的name屬性為data;**
**4.輸出變數obj指向的棧記憶體中儲存的堆記憶體的地址值中的資料name屬性的值。**
**如圖:**
![在這裡插入圖片描述](https://img2020.cnblogs.com/blog/1604228/202102/1604228-20210203142236320-826803067.gif)
**還有有個補充的**
```javascript
let obj = {
name : 'obj'
}
let data = obj;
data = {
name : 'data'
}
console.log('obj.name : ' + obj.name);//obj.name : obj
```
**具體流程如下:**
**1.在堆中開闢一塊記憶體,將物件儲存於其中,再在棧中開闢一塊記憶體,將新開闢的記憶體的地址值儲存到棧中,宣告變數obj,使obj指向棧中新開闢的這塊地址值;**
**2.在棧中再開闢一塊記憶體,將obj指向的記憶體中的值複製到新開闢的記憶體中來,宣告變數data,使data指向新開闢的這塊記憶體地址;**
**3.在堆中開闢一塊記憶體,將物件儲存於其中,將新開闢的記憶體的地址值儲存到變數data指向棧中地址值;**
**4.輸出變數obj指向的棧記憶體中儲存的堆記憶體的地址值中的資料name屬性的值。**
**如圖:**
![在這裡插入圖片描述](https://img2020.cnblogs.com/news/1604228/202102/1604228-20210203142237198-10026156