Array.prototype.reduce 全面解析【JS方法】

目录

  • [一、reduce 是什么?](#一、reduce 是什么?)
  • 二、核心参数解析
  • [三、reduce 执行机制(面试重点🔥)](#三、reduce 执行机制(面试重点🔥))
  • [四、手写 reduce](#四、手写 reduce)
  • [五、reduce 的 5 大核心用途](#五、reduce 的 5 大核心用途)
  • [六、reduce 面试高频考点](#六、reduce 面试高频考点)
    • [reduce 和 map 的区别?](#reduce 和 map 的区别?)
    • [reduce 如果不传 initialValue 会怎样?](#reduce 如果不传 initialValue 会怎样?)
    • [reduce 是否改变原数组?](#reduce 是否改变原数组?)
    • [空数组调用 reduce 会怎样?](#空数组调用 reduce 会怎样?)
  • [七、reduce 易错点](#七、reduce 易错点)
    • [1. 忘记 initialValue](#1. 忘记 initialValue)
    • [2. acc 类型混乱](#2. acc 类型混乱)
    • [3. return 忘写](#3. return 忘写)
    • [4. 修改 acc(副作用)](#4. 修改 acc(副作用))
  • 九、面试杀手题
    • [用 reduce 实现 flat](#用 reduce 实现 flat)
    • [用 reduce 实现 Promise 串行](#用 reduce 实现 Promise 串行)
  • 总结:

一、reduce 是什么?

reduce就是把数组"归并"为一个值(任意类型) (reduce = for 循环 + 累加器)

js 复制代码
arr.reduce((acc, cur, index, array) => {
  return acc + cur
}, initialValue)

二、核心参数解析

回调函数参数:

参数 含义
acc 累加器(核心)
cur 当前值
index 当前索引
array 原数组

initialValue(重点)

有 initialValue

javascript 复制代码
[1,2,3].reduce(fn, 10)

执行:

javascript 复制代码
acc = 10  
cur = 1

👉 从 index = 0 开始

没有 initialValue

javascript 复制代码
[1,2,3].reduce(fn)

执行:

javascript 复制代码
acc = 1(自动取 this[0])
cur = 2

👉 从 index = 1 开始

结论:给了初始值从第0项开始加,第一项是 initialValue;没给初始值第0项默认为初始值,从第一项开始添加。

三、reduce 执行机制(面试重点🔥)

执行流程:

  1. 初始化 acc
  2. 遍历数组
  3. 每次更新 acc
  4. 返回最终 acc

本质模型:

javascript 复制代码
acc = fn(acc, cur)

四、手写 reduce

javascript 复制代码
Array.prototype.myReduce = function(fn, init) { 
	let acc = init ?? this[0]; 
	let start = init ? 0 : 1;
	for (let i = start; i < this.length; i++) { 
		acc = fn(acc, this[i], i, this) 
	} 
	return acc 
}

五、reduce 的 5 大核心用途

求和:

javascript 复制代码
[1,2,3].reduce((a,b) => a + b, 0)

数组扁平化(flat):

javascript 复制代码
[[1,2],[3,4]].reduce((a,b) => a.concat(b), [])

计数统计:

javascript 复制代码
['a','b','a'].reduce((acc, cur) => {
  acc[cur] = (acc[cur] || 0) + 1
  return acc
}, {})

输出:

javascript 复制代码
{ a: 2, b: 1 }

数组转对象:

javascript 复制代码
[
  { id: 1, name: 'A' },
  { id: 2, name: 'B' }
].reduce((acc, cur) => {
  acc[cur.id] = cur
  return acc
}, {})

实现 map / filter(进阶):

  • map

使用map实现:

javascript 复制代码
[1,2,3].map(x => x * 2)

使用reduce实现:

javascript 复制代码
arr.reduce((acc, cur) => {
  acc.push(cur * 2)
  return acc
}, [])
  • filter

使用filter实现:

javascript 复制代码
[1,2,3].filter(x => x > 1)

使用reduce实现:

javascript 复制代码
arr.reduce((acc, cur) => {
  if (cur > 1) acc.push(cur)
  return acc
}, [])

六、reduce 面试高频考点

reduce 和 map 的区别?

方法 作用
map 一对一转换
reduce 任意归并

reduce 如果不传 initialValue 会怎样?

使用数组第一个元素;从 index = 1 开始

reduce 是否改变原数组?

不改变!!!!

空数组调用 reduce 会怎样?

javascript 复制代码
[].reduce(fn)

会报错!TypeError: Reduce of empty array with no initial value

七、reduce 易错点

1. 忘记 initialValue

javascript 复制代码
[].reduce(fn) // ❌ 报错

2. acc 类型混乱

javascript 复制代码
[1,2,3].reduce((a,b) => a + b, {})

类型错误!!!

3. return 忘写

javascript 复制代码
reduce((acc, cur) => {
  acc + cur   // ❌ 没 return
})

4. 修改 acc(副作用)

javascript 复制代码
acc.push(cur) // ⚠️ 需要注意引用类型

九、面试杀手题

用 reduce 实现 flat

javascript 复制代码
function flat(arr) {
  return arr.reduce((acc, cur) => {
    return acc.concat(Array.isArray(cur) ? flat(cur) : cur)
  }, [])
}

用 reduce 实现 Promise 串行

javascript 复制代码
function runTasks(tasks) {
  return tasks.reduce((prev, task) => {
    return prev.then(() => task())
  }, Promise.resolve())
}

总结:

reduce 是一个"把数组通过累加器转换成任意结果"的高阶函数,本质是 for 循环 + acc 累积模型。

相关推荐
小陈同学呦8 小时前
前端如何处理订单状态导航的数据竞态问题
前端·javascript
开发者每周简报8 小时前
网海三部曲·无名宗师传
javascript·人工智能
isyangli_blog9 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008119 小时前
FastAPI APIRouter
开发语言·python
Benszen9 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆9 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木9 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
杨充9 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~9 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言
basketball61610 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang