JavaScript 迴圈的進階應用可以解決複雜的資料處理、優化性能、處理異步操作和操作結構化數據等問題。
多維陣列是巢狀結構,需要巢狀迴圈來處理。為了處理如矩陣、表格數據這樣的資料結構,巢狀迴圈和遞迴經常被使用。
將矩陣的行和列進行轉換。
function transpose(matrix) {
const result = [];
for (let i = 0; i < matrix[0].length; i++) {
const row = [];
for (let j = 0; j < matrix.length; j++) {
row.push(matrix[j][i]);
}
result.push(row);
}
return result;
}
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log(transpose(matrix));
// [
// [1, 4, 7],
// [2, 5, 8],
// [3, 6, 9]
// ]
當你需要在迴圈中進行異步操作(如網路請求、資料庫查詢),使用 async
/await
是最佳選擇。這樣可以確保每次異步操作完成後再繼續下一個步驟。
async function fetchData(url) {
const response = await fetch(url);
const data = await response.json();
return data;
}
async function fetchMultipleData(urls) {
for (let url of urls) {
const data = await fetchData(url);
console.log(data);
}
}
const urls = ['https://api.example.com/1', 'https://api.example.com/2'];
fetchMultipleData(urls);
reduce()
進行陣列的高效處理reduce()
可以用來執行複雜的資料聚合邏輯,這對於需要處理大量數據的情況尤其有用。reduce()
可以取代多層次的巢狀迴圈,並使程式碼更簡潔。
const transactions = [
{ amount: 50 },
{ amount: 75 },
{ amount: 100 },
{ amount: 200 }
];
const total = transactions.reduce((sum, transaction) => sum + transaction.amount, 0);
console.log(total); // 425
break
在巢狀迴圈中,如果要中斷內外層的迴圈,傳統的 break
無法中斷外層迴圈。可以使用標籤(label)與 break
來達成這個需求。
outerLoop: // 定義標籤
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (i === 2 && j === 3) break outerLoop;
console.log(i, j);
}
}
// 輸出
// 0 0, 0 1, 0 2, 0 3, 0 4
// 1 0, 1 1, 1 2, 1 3, 1 4
// 2 0, 2 1, 2 2
使用生成器(Generator function),可以創建可中斷的迴圈,這在需要延遲計算或逐步生成數據時非常實用。
function* fibonacci() {
let a = 0, b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
處理大量資料時,為了優化性能,可以分批處理,避免一次操作太多資料導致性能下降。這種技術常用於處理大陣列、API 請求、或 DOM 操作。
function processBatch(items, batchSize) {
let index = 0;
function processNextBatch() {
const batch = items.slice(index, index + batchSize);
for (let item of batch) {
console.log(item);
}
index += batchSize;
if (index < items.length) {
setTimeout(processNextBatch, 100); // 延遲處理下一批
}
}
processNextBatch();
}
const largeArray = Array.from({ length: 1000 }, (_, i) => i + 1);
processBatch(largeArray, 100);
當處理大量數據或有昂貴的計算過程時,提前結束迴圈(如使用 break
、return
)或跳過無效計算(使用 continue
)可以提升性能。
function findFirstEven(numbers) {
for (let num of numbers) {
if (num % 2 === 0) return num; // 找到第一個偶數立即返回
}
return null;
}
console.log(findFirstEven([1, 3, 5, 7, 8, 9])); // 8
for await...of
處理異步可迭代物件這是一種用來處理異步可迭代數據的迴圈,適合用在需要逐一處理異步資料來源的情境(例如多個 API 請求)。
async function* asyncGenerator() {
const urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
for (const url of urls) {
const response = await fetch(url);
yield response.json();
}
}
(async function() {
for await (const data of asyncGenerator()) {
console.log(data);
}
})();
這些應用展示了 JavaScript 迴圈處理各種複雜情況的強大能力,無論是面對大量數據、提升程式的效率,還是處理異步操作。根據實際需求選擇合適的技巧,能讓程式碼更簡潔易懂,執行起來也更快更順。