JavaScript數(shù)組方法reduce使用詳解
一,前言
Reduce 是一種在函數(shù)式編程中常見的操作,它可以將一個序列(比如列表,數(shù)組)的所有元素通過某種規(guī)約邏輯合并成一個單一的數(shù)值。Reduce 的概念最早起源于函數(shù)式編程語言 Lisp,后來被廣泛應用于其他語言中,如 Python ,javaScript。本文會用最易懂的方式幫你徹底掌握JavaScript數(shù)組reduce()方法。我們先從基礎開始,逐步深入,最后通過實際案例鞏固知識,最重要的是希望能夠帶給你一些思考。
二,核心語法
arr.reduce(callback(accumulator, currentValue, index, array), initialValue)
Accumulator(累計值)
CurrentValue(當前元素)
Index(當前索引)
Array(原數(shù)組)
initialValue(Accumulator的初始值)
三,案例
1.求和
const nums = [1, 2, 3]; const sum = nums.reduce((acc, num) => acc + num, 0);
代碼分析:
此求和案例分別用了參數(shù)acc和num代表Accumulator和CurrentValue,并且將Accumulator的初始值賦為0。
運算步驟:
1,初始值為0,acc為0加第一次的當前值1 返回1
2,acc為1加第二次循環(huán)的當前值2,返回3
3,acc為3加第三次循環(huán)的當前值3,返回6
2.找最大值
const max = [4, 2, 7, 5].reduce((a, b) => Math.max(a, b), -Infinity);
代碼分析:
此求最大值案例分別用了參數(shù)a和b代表Accumulator和CurrentValue,并且將Accumulator的初始值賦為-Infinity(負無窮大)。
運算步驟:
1,首先是負無窮和第一次的當前值4比較,返回4
2,a為4,和第二次的當前值2比較,返回4
3,a為4,和第三次當前值7比較,返回7
4,a為7,和第四次當前值5比較,返回7
說明:
-Infinity 是 JavaScript 中的一個特殊值,表示負無窮大。它不是變量,而是一個全局屬性,屬于 JavaScript 的 基本數(shù)據(jù)類型 之一。
這里也可以更換 -Infinity為100,那么max的返回值就是100。
3.數(shù)組轉對象
const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const userMap = users.reduce((obj, user) => { obj[user.id] = user; return obj; }, {});
返回結果:
{ "1": { "id": 1, "name": "Alice" }, "2": { "id": 2, "name": "Bob" } }
說明:
數(shù)組轉對象案例這里主要是想體現(xiàn)一下設置初始值的重要性
這里如果不設置其默認初始值可以先看一下返回結果的區(qū)別
const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const userMap = users.reduce((obj, user) => { obj[user.id] = user; return obj; });
返回值:
{ "2": { "id": 2, "name": "Bob" }, "id": 1, "name": "Alice" }
代碼分析:
要想弄明白為什么沒有設置空的初始值顯示結果是這樣,我們首先回到案例1求和的代碼,之前我們分析結論是基于有返回值的情況下得出的
1,初始值為0,acc為0加第一次的當前值1 返回1
2,acc為1加第二次循環(huán)的當前值2,返回3
3,acc為3加第三次循環(huán)的當前值3,返回6
那么如果對于求和案例不設置初始值又該如何分析呢?
對于沒有設置初始值的reduce分析:第一次迭代時,acc 是數(shù)組的第一個元素,num 是數(shù)組的第二個元素。得到這個結論我們返回來分析代碼:
const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const userMap = users.reduce((obj, user) => { obj[user.id] = user; return obj; });
因為沒有返回值,第一次obj是 { id: 1, name: ‘Alice’ },user是 { id: 2, name: ‘Bob’ }
執(zhí)行 obj[user.id] = user 后,obj 變?yōu)?{ id: 1, name: ‘Alice’, 2: { id: 2, name: ‘Bob’ } }。
注意:
JavaScript的reduce函數(shù)有沒有設置初始值,直接影響第一次執(zhí)行的Accumulator和CurrentValue
4.復合操作(同時實現(xiàn) map + filter)
const numbers = [1, 2, 3, 4]; const doubledEvens = numbers.reduce((arr, num) => { if (num % 2 === 0) { arr.push(num * 2); } return arr; }, []); // 結果:[4, 8](先過濾偶數(shù),再翻倍)
代碼分析:
此求和案例分別用了參數(shù)arr和num代表Accumulator和CurrentValue,并且將Accumulator的初始值賦為[]。此例子中必須要設置Accumulator的初始值為[ ],否則,Accumulator的初始值是1,不是數(shù)組沒有push方法就會報錯。
四,常見錯誤
1.空數(shù)組沒有初始值
[].reduce((a, b) => a + b); // 報錯!
2.沒有返回累加值
// 錯誤示例 [1,2,3].reduce((acc, num) => { acc + num; // 沒有 return! }); // 正確:必須顯式返回 acc
reduce 方法在遍歷數(shù)組時,依賴于數(shù)組的長度和內容,如果在遍歷過程中修改了數(shù)組(例如刪除元素),會導致遍歷邏輯混亂,結果不可預測。
五,reduce 的 polyfill
Polyfill 是指在不支持某個新特性的舊瀏覽器中,用 JavaScript 實現(xiàn)該特性的代碼。換句話說,它是一個“補丁”,用來填補瀏覽器原生功能的缺失。
用白話說就是自己實現(xiàn)reduce,通過自己實現(xiàn) reduce,可以更深入地理解它的工作原理。
Array.prototype.myReduce = function (callback, initialValue) { // 1. 檢查 this 是否為 null 或 undefined if (this == null) { throw new TypeError('Array.prototype.myReduce called on null or undefined'); } // 2. 檢查 callback 是否是函數(shù) if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } const array = Object(this); // 將 this 轉換為對象 const length = array.length >>> 0; // 確保 length 是正整數(shù) let accumulator; let startIndex = 0; // 3. 處理初始值 if (arguments.length >= 2) { accumulator = initialValue; // 如果有初始值,直接使用 } else { // 如果沒有初始值,取數(shù)組的第一個元素作為初始值 if (length === 0) { throw new TypeError('Reduce of empty array with no initial value'); } accumulator = array[0]; startIndex = 1; // 從第二個元素開始遍歷 } // 4. 遍歷數(shù)組 for (let i = startIndex; i < length; i++) { if (i in array) { // 調用回調函數(shù),更新 accumulator accumulator = callback(accumulator, array[i], i, array); } } // 5. 返回最終結果 return accumulator; };
使用示例:
const nums = [1, 2, 3, 4]; // 求和 const sum = nums.myReduce((acc, num) => acc + num, 0); console.log(sum); // 10 // 找最大值 const max = nums.myReduce((acc, num) => Math.max(acc, num), -Infinity); console.log(max); // 4 // 數(shù)組轉字符串 const str = nums.myReduce((acc, num) => acc + num.toString(), ''); console.log(str); // '1234'
六,總結
reduce的參數(shù)看起來多,但是認真體會上面的案例不難理解,難點是如何記住
Accumulator(累計值)
CurrentValue(當前元素)
Index(當前索引)
Array(原數(shù)組)
參數(shù)順序口訣:“All Cows In Australia”(ACIA)
以上就是JavaScript數(shù)組方法reduce詳解的詳細內容,更多關于JavaScript方法reduce的資料請關注腳本之家其它相關文章!
相關文章
js實現(xiàn)1,2,3,5數(shù)字按照概率生成
這篇文章主要介紹了js實現(xiàn)1,2,3,5數(shù)字按照概率生成,需要的朋友可以參考下2017-09-09JavaScript是否可實現(xiàn)多線程 深入理解JavaScript定時機制
JavaScript的setTimeout與setInterval是兩個很容易欺騙別人感情的方法,因為我們開始常常以為調用了就會按既定的方式執(zhí)行, 我想不少人都深有同感,2009-12-12