0

0

一文吃透js中的Array.reduce方法

藏色散人

藏色散人

发布时间:2023-02-28 16:07:18

|

2593人浏览过

|

来源于juejin

转载

本篇文章给大家带来了关于js的相关知识,其中主要跟大家聊一聊js中的array.reduce方法,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。

前言

我们经常会用到 Array 对象的 reduce 方法,把它用于做一些计算、或者数据组合,发现自己用了那么多年 reduce ,竟然还不是很了解它,最近才发现如果不传递初始值,它也可以正常进行,数组也可以是一个函数数组,来增强我们的代码。

本篇文章将带你重来了解 Array.reduce 和运用场景。

重新了解 Array.reduce

我们来看一下 MDN 怎么描述它的:

reduce()  方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

我们来看一下这段代码:

const arr = [1, 2, 3]
const initValue = 10;
function reducer(previousValue, currentValue, currentIndex, arrryTarget) {
    return preValue + currentValue
}
arr.reduce(reducer, initValue) // res === 16

reduce 会遍历 arr 数组,数组有多少个,reducer 就会执行多少次。执行过程每一次的参数(arrryTarget都是一样的,因此没有意义,除非在遍历过程中直接改变了原数组,因此这里不考虑)如下:

reducer 重复执行 previousValue currentValue currentIndex return
第一次执行 10 1 0 11
第二次执行 11 2 1 13
第三次执行 13 3 2 16

这个过程用过 reduce 的应该都知道,MDN 上原话是这样的:

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)

也就是第一次执行 reducer 函数时,不存在“上一次的计算结果”。这里传递了初始值,因此 reducer 函数才从数组索引为 0 的元素开始执行,也就是 arr.length 等于 reducer 执行次数。

但如果不传递初始值呢?我们改动一下代码:

const arr = [1, 2, 3]
- const initValue = 10;
function reducer(previousValue, currentValue, currentIndex, arrryTarget) {
    return preValue + currentValue
}
- arr.reduce(reducer, initValue) // res === 16
+ arr.reduce(reducer) // res === 6

这时候 reducer 只会执行 arr.length - 1 次。执行过程每一次的参数如下:

reducer 重复执行 previousValue currentValue currentIndex return
第一次执行 1 2 1 3
第二次执行 3 3 2 6

因为没有传递初始值,因此 reducer 函数从数组索引为 1 的元素开始执行,首次执行的时候 arr[0] 被作为了 previousValuecurrentValue 为是 arr[1]

现在了 reduce 的基本用法,那么它的运用场景有哪些呢?

reduce 的运用场景

用于计算数据

因为 reducer 函数会重复执行 array.length 或者 array.length - 1,因此特别适合做一些计算。

纯js带缩略图的图片图集幻灯片特效
纯js带缩略图的图片图集幻灯片特效

这是一款使用纯js来制作的带缩略图的图片图集幻灯片特效。该图片幻灯片特效功能强大,可以直接使用鼠标进行前后导航,也可以通过缩略图来切换图片,还可以进入缩略图预览模式,查看所有的图片。 使用方法 在页面中引入base.css和gallery.css样式文件,以及BX.1.0.1.U.js、gallery.js和piclist.js文件。

下载

比如累加,计算订单总金额等案例:

const orders = [{ id: 1, amount: 10 }, { id: 2, amount: 12 }, { id: 3, amount: 5 }]
const totalAmount = orders.reduce((sum, order) => sum + order.amount, 0); // 27

累加可以,那么 加减乘除 中其他三个的原理是一样的,这里不用多说,肯定是可以的,甚至加上 的计算也是可以的,比如

[true, true, false, true].reduce((a, b) => a & b); // 有false,按照与逻辑,一定会是false

将多维数组转为一维数组

reduce 可以很轻松的将二维数组转为一维数组。示例:

[[1,2], [3, 4]].reduce((arrA, arrB) => [...arrA, ...arrB])

那是不是封装一下就可以把多维数组组转为一维数组了?当然可以:

function flaten(arr) {
    if(!Array.isArray(arr)) {
        return arr;
    }
    return arr.reduce((result, item) => {
        // 不是数组,则直接放在数组末尾
        if(!Array.isArray(item)) {
            result.push(item);
            return result;
        }
        return result.concat(flaten(item))
    }, [])
}
flaten([1,2, [3, 4], [6, [7, 8]]]) // [1, 2, 3, 4, 6, 7, 8]

这样就很简单的实现一个深层次的 flaten 。

将函数作为参数

将函数作为参数的话,运用场景在哪里?比如:

[func1, func2. func3, func4].reduce((value, funcN) => funcN(value), value),

执行顺序: func1 => func2 => func3 => func4,

这个效果就和 pipe 很像了是不是?这样封装一下就可以让函数执行扁平化。而不是 func1(func2(func3(func4(value)))) 这样看着难受。有一篇详细的描述了将函数作为参数来实现 pipe 和 compose 函数的过程,有兴趣可以点击去看看

其他场景

MDN 其实还描述了很多使用场景,大家都可以去探索一下,总之 reduce 的功能很强大,俗称“万金油”不是没有道理的。

这里就简单列一下:

  • 计算数组中每个元素出现的次数(如果元素是对象,也可以计算某个值出现的次数)
  • 按属性对 object 分类
  • 使用扩展运算符和 initialValue 绑定包含在对象数组中的数组
  • 数组去重
  • 使用 .reduce() 替换 .filter() 或者 .map(),可以替换当然也可以实现。
  • 按顺序运行 Promise
  • .....

最后

js中其实有很多函数功能都很强大,这些函数的强大其实还是因为js本身的机制带来的,函数在js中是一等公民,注定会逐渐影响我们的编码风格,因此大家可以去了解和学习函数式编程,它能让你的代码写的更轻松。

推荐学习:《JavaScript视频教程

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1503

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

233

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

87

2025.10.17

length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

928

2023.09.19

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

61

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

42

2025.11.27

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

30

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号