JS中常用的循環方法
1. for 循環
for 循環是最基本的循環方式,適合用於已知迭代次數的情況,例如遍歷陣列的索引。
語法
for (let i = 0; i < 陣列長度; i++) {
// 執行程式碼
}
範例
假設我們有一個陣列,包含一些水果名稱,我們想把每個水果名稱印出來:
const fruits = ['蘋果', '香蕉', '橘子'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
執行結果
蘋果
香蕉
橘子
步驟說明
-
宣告變數 i 作為索引,從 0 開始。
-
設定條件 i < fruits.length,確保不超過陣列長度。
-
每次循環結束,i++ 將索引加 1。
-
在循環內,使用 fruits[i] 存取陣列元素。
使用情境
-
當你需要精確控制索引或遍歷次數時。
-
適合處理陣列或需要跳躍索引的情況(例如每隔兩個元素處理一次)。
2. for...of 循環
for...of 是 ES6 引入的語法,專為遍歷可迭代對象(如陣列、字串)設計,語法簡單,無需手動管理索引。
語法
for (const 元素 of 可迭代對象) {
// 執行程式碼
}
範例
遍歷同樣的水果陣列:
const fruits = ['蘋果', '香蕉', '橘子'];
for (const fruit of fruits) {
console.log(fruit);
}
執行結果
蘋果
香蕉
橘子
步驟說明
-
使用 const fruit 宣告變數來接收每次迭代的元素。
-
of fruits 表示從 fruits 陣列中逐一取出元素。
-
直接使用 fruit 變數處理當前元素,無需索引。
使用情境
-
當你只需要陣列的元素值,不需要索引時。
-
適用於陣列、字串、Set、Map 等可迭代對象。
3. forEach 方法
forEach 是陣列的內建方法,用來對陣列中的每個元素執行指定的函數。它比 for 循環更簡潔,且語法更具可讀性。
語法
陣列.forEach((元素, 索引, 陣列) => {
// 執行程式碼
});
範例
遍歷水果陣列,並顯示元素和索引:
const fruits = ['蘋果', '香蕉', '橘子'];
fruits.forEach((fruit, index) => {
console.log(`索引 ${index}: ${fruit}`);
});
執行結果
索引 0: 蘋果
索引 1: 香蕉
索引 2: 橘子
步驟說明
-
forEach 接受一個回呼函數,該函數有三個參數:
-
元素(必須):當前遍歷的元素(例如 fruit)。
-
索引(可選):當前元素的索引(例如 index)。
-
陣列(可選):正在遍歷的原始陣列(例如 fruits)。
-
-
每次迭代會自動呼叫回呼函數,無需手動控制。
使用情境
-
當你想對陣列的每個元素執行相同的操作。
-
語法簡潔,適合取代 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); // 確認原始陣列未改變
執行結果
['蘋果', '香蕉', '橘子']
['蘋果', '香蕉', '橘子']
步驟說明
-
map 接受一個回呼函數,處理每個元素。
-
回呼函數的回傳值會組成新陣列。
-
原始陣列 fruits 不會被修改。
-
在這個例子中,toUpperCase() 將每個元素轉為大寫。
使用情境
-
當你需要將陣列元素轉換為新值並保留結果。
-
適合生成新資料,例如轉換格式或計算。
5. for...in 循環
for...in 主要用來遍歷物件的可枚舉屬性,不太建議用於陣列,因為它會遍歷所有屬性(包括原型鏈上的)。
語法
for (const 鍵 in 物件) {
// 執行程式碼
}
範例
遍歷一個物件的屬性:
const person = {
name: '小明',
age: 25,
city: '台北'
};
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
執行結果
name: 小明
age: 25
city: 台北
步驟說明
-
key 接收物件的屬性名稱(例如 name、age)。
-
使用 person[key] 取得屬性值。
-
遍歷所有可枚舉屬性。
使用情境
-
適合遍歷物件的鍵值對。
-
不建議用於陣列,因為可能遍歷到非預期的屬性。
6. while 循環
while 循環在條件為真時持續執行,適合不知道迭代次數的情況。
語法
while (條件) {
// 執行程式碼
}
範例
印出 1 到 5:
let i = 1;
while (i <= 5) {
console.log(i);
i++;
}
執行結果
1
2
3
4
5
步驟說明
-
宣告變數 i 作為計數器。
-
設定條件
i <= 5,只要條件為真就繼續執行。 -
在循環內,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
步驟說明
-
先執行 do 區塊內的程式碼。
-
檢查 while 條件,若為真則繼續循環。
-
在這個例子中,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 時,確保條件最終會變為假,以免進入無限循環。
-