Primitive vs Reference Data Types in JavaScript
Primitive vs Reference Data Types、Stack vs Heap、By Value vs By Reference、Shallow Copy vs Deep Copy
credit Primitive vs Reference Data Types in JavaScript
1. Primitive Data Types
JavaScript 的 Primitive Data Types(原始數據類型) 是不可變的,並且直接存儲在 Stack(堆疊) 記憶體中。
主要的 Primitive 類型
String(字串)
Number(數字)
Boolean(布林值)
Undefined(未定義)
Null(空值)
BigInt(大數值)
Symbol(符號)
特性
直接存儲在 Stack 記憶體中。
傳遞時是 By Value(按值傳遞),即複製值的副本。
不可變(Immutable),修改變數時實際上是創建新值,而非修改原值。
範例
let a = 10;
let b = a; // 複製值
b = 20;
console.log(a); // 10(a 不受影響)
console.log(b); // 20
2. Reference Data Types
Reference Data Types(引用數據類型) 是可變的,並且存儲在 Heap(堆記憶體) 中,變數實際上儲存的是該對象的引用(地址)。
主要的 Reference 類型
Object(物件)
Array(數組)
Function(函數)
Date(日期)
RegExp(正則表達式)
特性
存儲於 Heap 記憶體,變數存放的是指向 Heap 內存的地址。
傳遞時是 By Reference(按引用傳遞),即變數存儲的是對象的內存地址,而非值的副本。
可變(Mutable),對變數的修改會影響到原始對象。
範例
let obj1 = { name: "Alice" };
let obj2 = obj1; // obj2 取得 obj1 的記憶體地址
obj2.name = "Bob";
console.log(obj1.name); // "Bob"(obj1 被修改了)
3. Stack vs Heap
Stack(堆疊)
用於存儲 Primitive Data Types。
變數直接存儲其值。
內存分配是自動的,當變數超出作用域時,自動釋放內存。
Heap(堆)
用於存儲 Reference Data Types。
變數存儲的是對象的 內存地址,實際數據存儲在 Heap 中。
需要手動管理內存,JavaScript 使用 垃圾回收(Garbage Collection) 來回收不再使用的對象。
4. By Value vs By Reference
By Value(按值傳遞)
適用於 Primitive Data Types。
賦值時,會創建變數的副本,修改副本不會影響原始變數。
範例
let x = 100;
let y = x; // y 獲得 x 的值(複製)
y = 200;
console.log(x); // 100(x 不受影響)
By Reference(按引用傳遞)
適用於 Reference Data Types。
賦值時,變數存儲的是內存地址,修改副本會影響原始變數。
範例
let objA = { value: 1 };
let objB = objA;
objB.value = 2;
console.log(objA.value); // 2(objA 被影響)
5. Shallow Copy vs Deep Copy
Shallow Copy(淺拷貝)
只複製第一層的屬性,內部的引用類型仍然指向原內存地址。
修改內部對象時,原對象也會受到影響。
淺拷貝方式
Object.assign()
展開運算符
...
範例
let obj1 = { name: "Alice", details: { age: 25 } };
let obj2 = { ...obj1 }; // 淺拷貝
obj2.details.age = 30;
console.log(obj1.details.age); // 30(原對象受影響)
Deep Copy(深拷貝)
創建完全獨立的副本,所有層級的對象都會被複製。
修改新對象不會影響原對象。
深拷貝方式
JSON.parse(JSON.stringify(obj))
(不適用於函數和undefined
)structuredClone(obj)
(最新的深拷貝方法,支援所有類型)Lodash:
_.cloneDeep(obj)
(推薦)
範例
let obj1 = { name: "Alice", details: { age: 25 } };
let obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷貝
obj2.details.age = 30;
console.log(obj1.details.age); // 25(原對象不受影響)
6. 總結
類型 | 存儲位置 | 賦值方式 | 影響原對象 |
Primitive Data Types | Stack | By Value | ❌(不影響) |
Reference Data Types | Heap | By Reference | ✅(影響) |
Shallow Copy | Heap | By Reference(部分複製) | ✅(影響內部引用) |
Deep Copy | Heap | By Value(完全複製) | ❌(不影響) |
這篇文章詳細介紹了 JavaScript 的原始數據類型與引用數據類型的區別,並解析了 Stack vs Heap、By Value vs By Reference 以及 Shallow Copy vs Deep Copy,幫助你更好地理解 JavaScript 記憶體管理與數據操作方式。