文章目錄
- JavaScript內存管理完全指南:從入門到精通
- 1. 哪些數據類型屬于引用類型(復雜數據類型)?
- 2. 為什么引用類型要存儲在堆中?
- 3. 引用類型的內存存儲示例
- 示例 1:對象(Object)
- 示例 2:數組(Array)
- 示例 3:函數(Function)
- 4. 基本數據類型 vs. 引用數據類型
- 5. 特殊情況:`const` 聲明的引用類型
- 總結

JavaScript內存管理完全指南:從入門到精通
在 JavaScript 中,所有的復雜數據類型(引用類型)都遵循這個原則:
- 變量名(標識符)存儲在棧(Stack)中,并保存一個指向堆內存的引用地址(指針)。
- 實際的數據(如對象、數組、函數等)存儲在堆(Heap)中。
1. 哪些數據類型屬于引用類型(復雜數據類型)?
JavaScript 中的引用類型包括:
Object
(普通對象)Array
(數組)Function
(函數)Date
、RegExp
、Map
、Set
等內置對象- 自定義的類實例
這些類型的數據都存儲在堆中,而變量名(引用)存儲在棧中。
2. 為什么引用類型要存儲在堆中?
- 動態大小:引用類型(如對象、數組)的大小可能動態變化,堆內存可以靈活分配空間。
- 共享數據:多個變量可以引用同一個堆數據(節省內存)。
- 棧的限制:
- 棧內存較小,適合存儲固定大小的數據(如基本類型)。
- 棧主要用于函數調用棧幀(局部變量、返回地址等),不適合存儲大塊數據。
3. 引用類型的內存存儲示例
示例 1:對象(Object)
let obj1 = { name: "Alice" }; // `obj1` 在棧中存儲堆的引用,對象數據在堆中
let obj2 = obj1; // `obj2` 復制的是引用,指向同一個堆數據
obj2.name = "Bob"; // 修改會影響 `obj1`
console.log(obj1.name); // "Bob"(因為 obj1 和 obj2 指向同一個堆數據)
示例 2:數組(Array)
let arr1 = [1, 2, 3]; // `arr1` 在棧中存儲堆的引用
let arr2 = arr1; // `arr2` 復制的是引用
arr2.push(4); // 修改會影響 `arr1`
console.log(arr1); // [1, 2, 3, 4]
示例 3:函數(Function)
function greet() { console.log("Hello!"); }
let func1 = greet; // `func1` 存儲的是函數的引用
let func2 = func1; // `func2` 也指向同一個函數
func2(); // "Hello!"
4. 基本數據類型 vs. 引用數據類型
特性 | 基本數據類型(Primitive) | 引用數據類型(Reference) |
---|---|---|
存儲位置 | 變量名和值都在棧中 | 變量名(引用)在棧中,數據在堆中 |
賦值方式 | 值拷貝(復制值) | 引用拷貝(復制指針) |
修改影響 | 不影響其他變量 | 多個變量可能指向同一數據,修改會互相影響 |
示例 | let a = 10; | let obj = { x: 1 }; |
5. 特殊情況:const
聲明的引用類型
const
保證的是變量引用的地址不變,但堆中的數據仍然可以修改:const arr = [1, 2, 3]; arr.push(4); // 允許(修改堆數據) arr = [5, 6]; // 報錯(不能修改引用地址)
總結
? 所有復雜數據類型(引用類型)都遵循:變量名在棧中存儲引用地址,實際數據在堆中。
? 基本數據類型(number
、string
等)直接存儲在棧中。
? 理解這一點對避免 “淺拷貝 vs. 深拷貝”、“數據共享問題” 至關重要。