reduce 是 JavaScript 中數組的一個方法,用于通過遍歷元素一步步將數組轉換為一個結果。其基本結構是 Array.reduce((accumulator, currentvalue, index, array) => { … }, initialvalue),其中 accumulator 是累計值,currentvalue 是當前元素,initialvalue 是初始值。常見用途包括求數組總和、統計元素出現次數、數組扁平化、轉換成對象或樹形結構等。使用時需注意:必須返回 accumulator、建議提供初始值、避免復雜邏輯和副作用。典型用法如 1. 數組扁平化;2. 轉成 map 對象;3. 連續異步操作。掌握 reduce 的關鍵是理解其逐步匯總數據的機制。
reduce 是 JavaScript 中數組的一個方法,用來“一步步把數組里的元素算成一個結果”。這個結果可以是數字、字符串、對象、數組等。它不像 map 或 Filter 那樣返回一個新數組,而是通過一次次處理元素,最后匯總出一個值。
一、reduce 的基本結構
reduce 方法的語法如下:
array.reduce((accumulator, currentValue, index, array) => { // 返回新的 accumulator 值 }, initialValue)
- accumulator:累計器,上一次調用的結果。
- currentValue:當前處理的元素。
- index(可選):當前索引。
- array(可選):原數組。
- initialValue(可選):初始值,如果沒提供,會默認使用第一個元素作為初始值。
舉個簡單的例子,計算數組總和:
[1, 2, 3, 4].reduce((sum, num) => sum + num, 0); // 結果是 10
如果沒有給初始值 0,第一次執行時 sum 就是第一個元素 1,然后從第二個元素開始累加。
二、reduce 能做什么?
reduce 的強大之處在于它的靈活性。只要你想“遍歷數組并最終得到一個結果”,它都可以勝任。常見的用途包括:
- 求數組總和、平均值
- 統計元素出現次數
- 把數組轉換成對象或樹形結構
- 扁平化嵌套數組
例如統計每個單詞出現的次數:
const words = ['apple', 'banana', 'apple', 'orange']; const count = words.reduce((acc, word) => { acc[word] = (acc[word] || 0) + 1; return acc; }, {}); // 結果:{ apple: 2, banana: 1, orange: 1 }
三、reduce 使用時要注意什么?
雖然 reduce 功能強大,但使用不當容易出錯。以下是幾個常見注意事項:
-
別忘了返回 accumulator
如果在回調中沒有返回值,下一輪就得不到正確的累計結果。 -
初始值不是必須的,但最好加上
不加的話,如果數組為空會報錯;而且邏輯更清晰。 -
不要在 reduce 里做太復雜的事
如果你的 reduce 回調函數超過幾行,建議拆分成小函數或者考慮其他方法。 -
避免副作用
比如在 reduce 里面修改外部變量,會讓代碼難以理解和調試。
四、實際開發中的典型用法
有時候你可能沒想到可以用 reduce,其實它能解決不少實際問題:
1. 數組扁平化
const arr = [1, [2, [3, 4], 5]]; const flat = arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), []);
2. 把數組轉成 map 或對象
const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const userMap = users.reduce((map, user) => { map[user.id] = user; return map; }, {});
3. 連續異步操作
雖然不推薦直接在 reduce 里寫異步邏輯,但如果你真想串行執行多個 promise,也可以這么寫:
fetchList.reduce((prevPromise, item) => { return prevPromise.then(() => fetchItem(item)); }, Promise.resolve());
基本上就這些了。掌握 reduce 的關鍵是理解它是如何一步步“收攏”數據的。剛學的時候可能會覺得繞,但多練幾次就能體會到它的靈活與強大。