本文 AI 產出,尚未審核
JavaScript 陣列操作(Arrays)— 陣列建立與索引
簡介
在 JavaScript 中,陣列(Array)是最常用的資料結構之一。無論是處理使用者輸入、串接 API 回傳的資料,或是實作演算法,陣列都是不可或缺的基礎工具。
本單元聚焦於「陣列建立」與「索引」兩大核心概念,讓讀者能快速掌握如何正確產生、存取與操作陣列元素。掌握這些技巧後,你將能在日常開發中更加自如地處理集合資料,為後續的排序、過濾、映射等進階操作奠定堅實基礎。
核心概念
1. 陣列的基本建立方式
JavaScript 提供多種語法建立陣列,最常見的有:
| 建立方式 | 語法 | 說明 |
|---|---|---|
| 字面量(Literal) | const arr = [1, 2, 3]; |
直接寫入元素,最直觀且效能佳。 |
Array 建構子 |
const arr = new Array(5); |
產生指定長度的空陣列(元素為 empty),或 new Array(...items) 直接傳入元素。 |
Array.of |
const arr = Array.of(7); |
產生包含單一元素的陣列,避免 new Array(7) 被誤解為長度。 |
Array.from |
const arr = Array.from('abc'); |
從類陣列或可迭代物件(如字串、Set)建立陣列。 |
程式碼範例 1:字面量與建構子
// 使用字面量建立陣列
const fruits = ['蘋果', '香蕉', '橘子'];
console.log(fruits); // ["蘋果", "香蕉", "橘子"]
// 使用建構子建立固定長度的空陣列
const emptySlots = new Array(3);
console.log(emptySlots); // [ <3 empty items> ]
// 使用建構子直接放入元素
const numbers = new Array(1, 2, 3);
console.log(numbers); // [1, 2, 3]
註:
new Array(3)只會產生長度為 3、但每個位置都是 empty,不等同於[undefined, undefined, undefined]。
2. 陣列的索引與存取
陣列的每個元素都有一個 0 起始的索引(index),透過 arr[index] 直接存取或修改。
程式碼範例 2:基本存取與更新
const colors = ['紅', '綠', '藍'];
// 讀取索引 1 的元素
console.log(colors[1]); // "綠"
// 更新索引 2 的元素
colors[2] = '黃';
console.log(colors); // ["紅", "綠", "黃"]
// 讀取不存在的索引會得到 undefined
console.log(colors[5]); // undefined
3. 動態增減元素
雖然陣列的長度是可變的,但在實務開發中,我們常使用以下方法來 在尾端或頭端 增減元素:
| 方法 | 位置 | 語法 | 回傳值 |
|---|---|---|---|
push |
尾端 | arr.push(item) |
新的長度 |
pop |
尾端 | arr.pop() |
被移除的元素 |
unshift |
頭端 | arr.unshift(item) |
新的長度 |
shift |
頭端 | arr.shift() |
被移除的元素 |
程式碼範例 3:使用 push / pop
let stack = [];
// push 進入元素
stack.push(10);
stack.push(20);
console.log(stack); // [10, 20]
// pop 移除最後一個元素
const top = stack.pop();
console.log(top); // 20
console.log(stack); // [10]
4. 多維陣列與矩陣表示
在處理表格、棋盤或座標系統時,常會使用 陣列的陣列(二維或更高維度)。
程式碼範例 4:建立 3×3 棋盤
// 建立 3x3 的二維陣列,初始值皆為 0
const board = Array.from({ length: 3 }, () => Array(3).fill(0));
console.log(board);
// [
// [0, 0, 0],
// [0, 0, 0],
// [0, 0, 0]
// ]
// 設定中心格子為 1
board[1][1] = 1;
console.log(board[1][1]); // 1
5. 使用 Symbol.iterator 直接遍歷
陣列本身實作了可迭代協定(Iterable),可以直接在 for...of 迴圈中使用,不需要額外的 .length 判斷。
程式碼範例 5:遍歷陣列
const pets = ['狗', '貓', '魚'];
for (const pet of pets) {
console.log(`我有一隻 ${pet}`);
}
// 輸出:
// 我有一隻 狗
// 我有一隻 貓
// 我有一隻 魚
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
使用 new Array(n) 產生空洞 |
產生的陣列每個位置都是 empty,map、forEach 等方法不會被呼叫。 |
若要建立固定長度且每個元素都有值,使用 Array.from({length:n}, (_,i)=>i) 或 Array(n).fill(undefined)。 |
| 索引超出範圍仍不會拋錯 | 讀取不存在的索引會回傳 undefined,容易產生隱蔽 bug。 |
在存取前先檢查 index >= 0 && index < arr.length,或使用 Array.prototype.at()(支援負索引)。 |
直接改變 length 屬性 |
設定 arr.length = 0 會清空陣列,若不小心使用可能導致資料遺失。 |
使用 arr.splice(0) 或 arr = [](重新指派)以表達「清空」的意圖。 |
| 混用稀疏陣列與密集陣列 | 稀疏陣列(有空洞)在迭代時效能較差。 | 儘量保持陣列密集;若需要「缺值」概念,可使用 null 或 undefined 佔位。 |
忘記 const vs let |
陣列本身是物件,const 只保證變數指向不變,仍可修改內容。 |
若不希望陣列被重新指派,使用 const;若需要重新指派,使用 let。 |
最佳實踐小結
- 優先使用字面量建立陣列,語意清晰且效能最佳。
- 避免稀疏陣列,若需要預先分配長度,使用
Array.from搭配fill。 - 使用
Array.prototype.at()取得正負索引,提升可讀性。 - 保持陣列不可變(immutable)概念:在需要「變更」時,使用
slice、concat、展開運算子 (...) 產生新陣列,減少副作用。
// 以不可變方式加入新元素
const original = [1, 2, 3];
const added = [...original, 4]; // [1,2,3,4]
console.log(original); // [1,2,3] 仍保持不變
實際應用場景
| 場景 | 為何需要陣列 | 典型操作 |
|---|---|---|
| 表單驗證 | 收集多筆錯誤訊息 | errors.push(message)、errors.join('\n') |
| API 分頁 | 處理回傳的多筆資料 | data.slice(start, end)、data.map(item => ...) |
| 圖形繪製 | 座標點集合 | 二維陣列或 [{x, y}, …],使用 forEach 繪製 |
| 狀態管理(如 Redux) | 列表型狀態(購物車、待辦清單) | state.concat(newItem)、state.filter(id => …) |
| 演算法練習(排序、搜尋) | 需要隨機存取與交換元素 | arr[i] = arr[j];、arr.sort() |
範例:簡易待辦清單(Todo List)
let todos = []; // 使用 const 也可以,只要不重新指派 // 新增任務 function addTask(task) { todos = [...todos, { id: Date.now(), text: task, done: false }]; } // 標記完成 function toggleDone(id) { todos = todos.map(t => t.id === id ? { ...t, done: !t.done } : t); } // 取得未完成任務 const pending = todos.filter(t => !t.done); console.log(pending);這段程式展示了 陣列的建立、展開運算子、
map、filter,是日常前端開發中常見的模式。
總結
本篇文章從 陣列的建立方式、索引存取、動態增減、多維陣列、可迭代遍歷 五個面向,提供了完整且實務導向的說明與範例。透過掌握這些基礎,你可以:
- 快速產生符合需求的陣列結構
- 正確、安全地存取與更新元素
- 避免常見的稀疏陣列與索引錯誤
- 在實務專案(如表單驗證、API 處理、狀態管理)中靈活運用
記得在開發時 以可讀性、效能與不可變性 為原則選擇適當的陣列操作方式,讓程式碼更易維護、錯誤更易追蹤。祝你在 JavaScript 陣列的世界裡玩得開心,寫出更健壯的程式!