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 累积模型。

相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int1 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端