Skip to main content

JS中常用的循環方法

1. for 循環

for 循環是最基本的循環方式,適合用於已知迭代次數的情況,例如遍歷陣列的索引。

語法

for (let i = 0; i < 陣列長度; i++) {
// 執行程式碼
}

範例

假設我們有一個陣列,包含一些水果名稱,我們想把每個水果名稱印出來:

const fruits = ['蘋果', '香蕉', '橘子'];

for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}

執行結果

蘋果
香蕉
橘子

步驟說明

  1. 宣告變數 i 作為索引,從 0 開始。

  2. 設定條件 i < fruits.length,確保不超過陣列長度。

  3. 每次循環結束,i++ 將索引加 1。

  4. 在循環內,使用 fruits[i] 存取陣列元素。

使用情境

  • 當你需要精確控制索引或遍歷次數時。

  • 適合處理陣列或需要跳躍索引的情況(例如每隔兩個元素處理一次)。


2. for...of 循環

for...of 是 ES6 引入的語法,專為遍歷可迭代對象(如陣列、字串)設計,語法簡單,無需手動管理索引。

語法

for (const 元素 of 可迭代對象) {
// 執行程式碼
}

範例

遍歷同樣的水果陣列:

const fruits = ['蘋果', '香蕉', '橘子'];

for (const fruit of fruits) {
console.log(fruit);
}

執行結果

蘋果
香蕉
橘子

步驟說明

  1. 使用 const fruit 宣告變數來接收每次迭代的元素。

  2. of fruits 表示從 fruits 陣列中逐一取出元素。

  3. 直接使用 fruit 變數處理當前元素,無需索引。

使用情境

  • 當你只需要陣列的元素值,不需要索引時。

  • 適用於陣列、字串、Set、Map 等可迭代對象。


3. forEach 方法

forEach 是陣列的內建方法,用來對陣列中的每個元素執行指定的函數。它比 for 循環更簡潔,且語法更具可讀性。

語法

陣列.forEach((元素, 索引, 陣列) => {
// 執行程式碼
});

範例

遍歷水果陣列,並顯示元素和索引:

const fruits = ['蘋果', '香蕉', '橘子'];

fruits.forEach((fruit, index) => {
console.log(`索引 ${index}: ${fruit}`);
});

執行結果

索引 0: 蘋果
索引 1: 香蕉
索引 2: 橘子

步驟說明

  1. forEach 接受一個回呼函數,該函數有三個參數:

    • 元素(必須):當前遍歷的元素(例如 fruit)。

    • 索引(可選):當前元素的索引(例如 index)。

    • 陣列(可選):正在遍歷的原始陣列(例如 fruits)。

  2. 每次迭代會自動呼叫回呼函數,無需手動控制。

使用情境

  • 當你想對陣列的每個元素執行相同的操作。

  • 語法簡潔,適合取代 for 循環。

  • 注意:forEach 無法中途跳出循環(不能用 break 或 return 終止)。


4. map 方法

map 方法遍歷陣列並對每個元素執行操作,返回一個新陣列,原始陣列不會被修改。常用於資料轉換。

語法

const 新陣列 = 陣列.map((元素, 索引, 陣列) => {
// 回傳新元素
});

範例

將水果名稱轉為大寫:

const fruits = ['蘋果', '香蕉', '橘子'];

const upperFruits = fruits.map(fruit => {
return fruit.toUpperCase();
});

console.log(upperFruits);
console.log(fruits); // 確認原始陣列未改變

執行結果

['蘋果', '香蕉', '橘子']
['蘋果', '香蕉', '橘子']

步驟說明

  1. map 接受一個回呼函數,處理每個元素。

  2. 回呼函數的回傳值會組成新陣列。

  3. 原始陣列 fruits 不會被修改。

  4. 在這個例子中,toUpperCase() 將每個元素轉為大寫。

使用情境

  • 當你需要將陣列元素轉換為新值並保留結果。

  • 適合生成新資料,例如轉換格式或計算。


5. for...in 循環

for...in 主要用來遍歷物件的可枚舉屬性,不太建議用於陣列,因為它會遍歷所有屬性(包括原型鏈上的)。

語法

for (constin 物件) {
// 執行程式碼
}

範例

遍歷一個物件的屬性:

const person = {
name: '小明',
age: 25,
city: '台北'
};

for (const key in person) {
console.log(`${key}: ${person[key]}`);
}

執行結果

name: 小明
age: 25
city: 台北

步驟說明

  1. key 接收物件的屬性名稱(例如 name、age)。

  2. 使用 person[key] 取得屬性值。

  3. 遍歷所有可枚舉屬性。

使用情境

  • 適合遍歷物件的鍵值對。

  • 不建議用於陣列,因為可能遍歷到非預期的屬性。


6. while 循環

while 循環在條件為真時持續執行,適合不知道迭代次數的情況。

語法

while (條件) {
// 執行程式碼
}

範例

印出 1 到 5:

let i = 1;

while (i <= 5) {
console.log(i);
i++;
}

執行結果

1
2
3
4
5

步驟說明

  1. 宣告變數 i 作為計數器。

  2. 設定條件 i <= 5,只要條件為真就繼續執行。

  3. 在循環內,i++ 確保最終會跳出循環,否則可能進入無限循環。

使用情境

  • 當迭代次數不確定,需依據條件控制。

  • 例如等待某個條件成立(像使用者輸入)。


7. do...while 循環

do...while 類似 while,但保證至少執行一次,因為它先執行再檢查條件。

語法

do {
// 執行程式碼
} while (條件);

範例

印出 1 到 5:

javascript

let i = 1;

do {
console.log(i);
i++;
} while (i <= 5);

執行結果

1
2
3
4
5

步驟說明

  1. 先執行 do 區塊內的程式碼。

  2. 檢查 while 條件,若為真則繼續循環。

  3. 在這個例子中,i++ 確保最終跳出循環。

使用情境

  • 當你希望程式碼至少執行一次。

  • 例如需要先顯示內容,再根據條件決定是否繼續。


總結與比較

以下是這些循環方法的比較,幫助你選擇合適的方法:

方法適用對象是否修改原始資料是否可中途跳出特色
for陣列、索引看程式碼邏輯可(break)精確控制索引,靈活性高
for...of可迭代對象(陣列、字串等)看程式碼邏輯可(break)語法簡單,無需管理索引
forEach陣列看程式碼邏輯不可簡潔,適合簡單遍歷
map陣列不修改(返回新陣列)不可用於資料轉換,生成新陣列
for...in物件看程式碼邏輯可(break)適合物件屬性遍歷
while條件不確定看程式碼邏輯可(break)靈活,適合不確定次數的循環
do...while條件不確定看程式碼邏輯可(break)至少執行一次

實用建議

  • 初學者推薦:開始時多用 forEach 或 for...of,因為語法簡單且易讀。

  • 前端開發常見場景:使用 map 處理資料轉換(例如準備顯示在元件中的資料)。

  • 注意事項

    • 避免在 forEach 中使用 return 來跳出循環,改用 for 或 for...of。

    • 處理物件時,優先使用 for...in 或 Object.keys()。

    • 使用 while 或 do...while 時,確保條件最終會變為假,以免進入無限循環。