WeHelp
深入理解 JavaScript 的型別操作與陣列變異行為
2025-06-26 02:10:23
## 請問以下程式碼執行結果是什麼? ```js let name = 'cindy' name[0] = 'C' console.log(name) ``` A:你可能會直覺以為輸出 `'Cindy'`,但實際結果會是: ``` cindy ``` ## 為什麼不能改變字串的內容? 因為 `string` 是 **原始型別(primitive type)**,它是 **不可變的(immutable)**。 在 JavaScript 中,原始型別(如 `string`, `number`, `boolean`): * 儲存在 **stack 記憶體中** * 一旦建立後就不能修改 * 若要改變,只能「整個覆寫」 例如: ```js let name = 'cindy' name = 'C' + name.slice(1) console.log(name) // 'Cindy' ``` ## 那這段程式碼又會輸出什麼? ```js let nameArray = ['alen', 'tim', 'kevin'] nameArray[0] = 'Alen' console.log(nameArray) ``` A: ``` ['Alen', 'tim', 'kevin'] ``` 這次成功改變了第一個元素的值,為什麼? ## 為什麼陣列可以改變內容? 因為陣列是 **參考型別(reference type)**: * 儲存在 stack 的是「指向 heap 的參考(pointer)」 * 改變內容時,其實是**透過這個參考去修改 heap 記憶體的值** 這不違反 `let` 或 `const` 的限制,因為我們**沒有改變參考位置**,只是改了它所參考的內容。 ## 那如果我用 `const` 宣告陣列,可以改變內容嗎? ```js const color = ['red', 'blue', 'yellow'] color[0] = 'green' console.log(color) ``` A: ``` ['green', 'blue', 'yellow'] ``` 即使是 `const` 宣告的陣列,也**可以改變內容**! ## 那 `const` 到底保護了什麼? `const` 保護的是: > 🔒 **變數所綁定的參考記憶體位置(binding)不能被重新指派** 但它**沒有凍結 heap 中的值**。你仍可以透過這個參考去修改內容。 ### 所以這會報錯: ```js const color = ['red'] color = ['green'] // ❌ TypeError ``` 但這是合法的: ```js color[0] = 'green' // ✅ OK ``` ### 開發上的實務建議: > 在大多數情況下,你應該預設用 `const` 來宣告 array 和 object,這樣可以避免無意中重新賦值(例如函式中的重複設值或被覆蓋),讓你的 code 更有預測性與安全性。 ## `array[3] = 4` 跟 `array.push(4)` 有什麼差別? ```js const arr = [1, 2, 3] arr[3] = 4 console.log(arr) arr.push(5) console.log(arr) ``` A: ```js [1, 2, 3, 4] [1, 2, 3, 4, 5] ``` 兩者都可以「新增元素」,但行為差異在於: | 操作方式 | 說明 | | ------------- | ----------------- | | `arr.push(x)` | 將元素插入**最後一格**(自動) | | `arr[n] = x` | 插入**指定位置**,可能會跳號 | 若你這樣做: ```js arr[10] = 'x' ``` 你會得到一個 **稀疏陣列**: ```js [1, 2, 3, 4, 5, <5 empty items>, 'x'] ``` 這在某些 JS 引擎會降低效能。 ## 結語 > 觀察「變數的操作方式」是理解型別的另一個視角 * 若你改變變數的值,觀察是否會改變參考位置或內容 * 若它是原始型別,你只能用覆蓋方式重新賦值 * 若它是參考型別(array/object),你可以透過 pointer 改變內容 ### 🔁 總整理:操作行為對照表 | 型別 | 是否 mutable | 是否可改內容 | 是否可重新賦值 (`const`) | | -------- | ---------- | ------ | ----------------- | | `string` | ❌ 否 | ❌ 否 | ❌ 否 | | `array` | ✅ 是 | ✅ 是 | ❌ 否(內容可改,參考不可換) | | `object` | ✅ 是 | ✅ 是 | ❌ 否(同上) | ## 參考資料 * [MDN Web Docs - JavaScript Data Types and Structures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures) * [MDN - Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) * [Udemy - The Web Developer Bootcamp 2025](https://www.udemy.com/course/the-web-developer-bootcamp/) by Colt Steele