本文 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) 產生空洞 產生的陣列每個位置都是 emptymapforEach 等方法不會被呼叫。 若要建立固定長度且每個元素都有值,使用 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 = [](重新指派)以表達「清空」的意圖。
混用稀疏陣列與密集陣列 稀疏陣列(有空洞)在迭代時效能較差。 儘量保持陣列密集;若需要「缺值」概念,可使用 nullundefined 佔位。
忘記 const vs let 陣列本身是物件,const 只保證變數指向不變,仍可修改內容。 若不希望陣列被重新指派,使用 const;若需要重新指派,使用 let

最佳實踐小結

  1. 優先使用字面量建立陣列,語意清晰且效能最佳。
  2. 避免稀疏陣列,若需要預先分配長度,使用 Array.from 搭配 fill
  3. 使用 Array.prototype.at() 取得正負索引,提升可讀性。
  4. 保持陣列不可變(immutable)概念:在需要「變更」時,使用 sliceconcat、展開運算子 (...) 產生新陣列,減少副作用。
// 以不可變方式加入新元素
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);

這段程式展示了 陣列的建立、展開運算子、mapfilter,是日常前端開發中常見的模式。


總結

本篇文章從 陣列的建立方式索引存取動態增減多維陣列可迭代遍歷 五個面向,提供了完整且實務導向的說明與範例。透過掌握這些基礎,你可以:

  • 快速產生符合需求的陣列結構
  • 正確、安全地存取與更新元素
  • 避免常見的稀疏陣列與索引錯誤
  • 在實務專案(如表單驗證、API 處理、狀態管理)中靈活運用

記得在開發時 以可讀性、效能與不可變性 為原則選擇適當的陣列操作方式,讓程式碼更易維護、錯誤更易追蹤。祝你在 JavaScript 陣列的世界裡玩得開心,寫出更健壯的程式!