JavaScript reduce() 方法详解:从基础语法到高级应用

作者:拾光

时间:2026-10-24

浏览:213

本文深入解析JavaScript中reduce()方法的语法与核心机制,涵盖prev、cur等参数含义。通过求和、求最大值、数组去重等基础实例展示其用法,并进一步讲解reduceRight()及与其他迭代方法的区别。进阶部分包含字符串统计、数组转对象、加权计算及Redux compose源码实现,帮助开发者掌握这一强大的数组归并工具。

文章目录

过去很长一段时间,我对 reduce() 方法的具体应用感到困惑,日常开发中也较少使用。实际上,一旦深入理解其原理,它将在众多场景中发挥重要作用。本文将简要探讨 JavaScript 中 reduce() 的核心用法。

一、语法

arr.reduce(function(prev,cur,index,arr){ ... }, init);

参数说明如下: arr 代表原始数组; prev 表示上一次调用回调函数时的返回值,或者初始值 init; cur 表示当前正在处理的数组元素; index 表示当前正在处理的数组元素的索引,若提供 init 值,则索引从 0 开始,否则从 1 开始; init 表示初始值。

乍看之下似乎较为复杂,但实际常用的参数仅有两个:prev 和 cur。接下来通过具体实例来演示其用法。

二、实例

首先准备一个原始数组:


var arr = [3,9,4,3,6,0,9];

实现上述需求有多种方式,其中使用 reduce() 是一种较为简洁的实现方案。

1. 求数组项之和


var sum = arr.reduce(function (prev, cur) {
    return prev + cur;
},0);

由于传入了初始值 0,初始时 prev 为 0,cur 为数组第一项 3,两者相加返回 3 作为下一轮回调的 prev 值,随后继续与后续数组项相加,依此类推,直至完成所有数组项的累加并返回结果。

2. 求数组项最大值


var max = arr.reduce(function (prev, cur) {
    return Math.max(prev,cur);
});

由于未传入初始值,初始时 prev 为数组第一项 3,cur 为数组第二项 9,取两者较大值后进入下一轮回调。

3. 数组去重


var newArr = arr.reduce(function (prev, cur) {
    prev.indexOf(cur) === -1 && prev.push(cur);
    return prev;
},[]);

实现的基本原理如下:

① 初始化一个空数组 ② 将需要去重处理的数组中的第 1 项在初始化数组中查找,如果找不到(空数组中肯定找不到),就将该项添加到初始化数组中 ③ 将需要去重处理的数组中的第 2 项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中 ④ …… ⑤ 将需要去重处理的数组中的第 n 项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中 ⑥ 将这个初始化数组返回

三、其他相关方法

1. reduceRight()

该方法的用法与 reduce() 相同,区别在于遍历方向相反,它从数组的最后一项开始,向前遍历至第一项。

2. forEach()、map()、every()、some()和filter()

详情请参考:JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍

重点总结:

reduce() 是数组的归并方法,与 forEach()、map()、filter() 等迭代方法一样,都会对数组每一项进行遍历。但 reduce() 的独特之处在于,它可以将前面数组项遍历产生的结果与当前遍历项进行运算,这是其他迭代方法所不具备的功能。

先看w3c语法


array.reduce(function(total, currentValue, currentIndex, arr), initialValue);
/*
  total: 必需。初始值, 或者计算结束后的返回值。
  currentValue: 必需。当前元素。
  currentIndex: 可选。当前元素的索引;                     
  arr: 可选。当前元素所属的数组对象。
  initialValue: 可选。传递给函数的初始值,相当于total的初始值。
*/

常见用法

数组求和


const arr = [12, 34, 23];
const sum = arr.reduce((total, num) => total + num);
<!-- 设定初始值求和 -->
const arr = [12, 34, 23];
const sum = arr.reduce((total, num) => total + num, 10);  // 以10为初始值求和
<!-- 对象数组求和 -->
var result = [
  { subject: 'math', score: 88 },
  { subject: 'chinese', score: 95 },
  { subject: 'english', score: 80 }
];
const sum = result.reduce((accumulator, cur) => accumulator + cur.score, 0); 
const sum = result.reduce((accumulator, cur) => accumulator + cur.score, -10);  // 总分扣除10分

进阶用法数组对象中的用法


const a = [23,123,342,12];
const max = a.reduce(function(pre,cur,inde,arr){return pre>cur?pre:cur;}); // 342

<!-- 比如生成“老大、老二和老三” -->

const objArr = [{name: '老大'}, {name: '老二'}, {name: '老三'}];
const res = objArr.reduce((pre, cur, index, arr) => {
  if (index === 0) {
    return cur.name;
  }
  else if (index === (arr.length - 1)) {
    return pre + '和' + cur.name;
  }
  else {
    return pre + '、' + cur.name;
  }
}, '');

求字符串中字母出现的次数


const str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmxzmnha';
const res = str.split('').reduce((accumulator, cur) => {accumulator[cur] ? accumulator[cur]++ : accumulator[cur] = 1; return accumulator;}, {});

数组转对象

<!-- 按照一定的规则转成数组 -->


var arr1 = [2, 3, 4, 5, 6]; // 每个值的平方
var newarr = arr1.reduce((accumulator, cur) => {accumulator.push(cur * cur); return accumulator;}, []);

高级用法多维的叠加执行操作

<!-- 按照id 取出stream -->


var streams = [{name: '技术', id: 1}, {name: '设计', id: 2}];
var obj = streams.reduce((accumulator, cur) => {accumulator[cur.id] = cur; return accumulator;}, {});

高级用法 多维的叠加执行操作

<!-- 各科成绩占比重不一样, 求结果 -->


var result = [
  { subject: 'math', score: 88 },
  { subject: 'chinese', score: 95 },
  { subject: 'english', score: 80 }
];
var dis = {
    math: 0.5,
    chinese: 0.3,
    english: 0.2
};
var res = result.reduce((accumulator, cur) => dis[cur.subject] * cur.score + accumulator, 0);

<!-- 加大难度, 商品对应不同国家汇率不同,求总价格 -->


var prices = [{price: 23}, {price: 45}, {price: 56}];
var rates = {
  us: '6.5',
  eu: '7.5',
};
var initialState = {usTotal:0, euTotal: 0};
var res = prices.reduce((accumulator, cur1) => Object.keys(rates).reduce((prev2, cur2) => {
  console.log(accumulator, cur1, prev2, cur2);
  accumulator[`${cur2}Total`] += cur1.price * rates[cur2];
  return accumulator;
}, {}), initialState);

var manageReducers = function() {
  return function(state, item) {
    return Object.keys(rates).reduce((nextState, key) => {
        state[`${key}Total`] += item.price * rates[key];
        return state;
      }, {});
  }
};
var res1= prices.reduce(manageReducers(), initialState);

扁平一个二维数组


var arr = [[1, 2, 8], [3, 4, 9], [5, 6, 10]];
var res = arr.reduce((x, y) => x.concat(y), []);

对象数组去重


const hash = {};
  chatlists = chatlists.reduce((obj, next: Object) => {
    const hashId = `${next.topic}_${next.stream_id}`;
    if (!hash[hashId]) {
      hash[`${next.topic}_${next.stream_id}`] = true;
      obj.push(next);
    }
    return obj;
  }, []);

compose函数 redux compose源码实现


function compose(...funs) {
    if (funs.length === 0) {
        return arg => arg;
    }
    if (funs.length === 1) {
       return funs[0];
    }
    return funs.reduce((a, b) => (...arg) => a(b(...arg)))

}


到此这篇关于JS中的reduce()方法使用小结的文章就介绍到这了,更多相关js reduce()方法内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章