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

相关推荐
kyriewen18 小时前
别再 console.log 了:5 个 Chrome DevTools 调试技巧,用过就回不去了
前端·javascript·面试
To_OC20 小时前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
GuWenyue21 小时前
排序效率低?5分钟吃透快速排序,性能飙升至O(nlogn)
前端·javascript·面试
何时梦醒21 小时前
深入理解递归与快速排序 —— 从基础入门到手写实现
前端·javascript
bonechips1 天前
LLM 的无状态:从 HTTP 协议到对话上下文工程
前端·javascript
胡志辉1 天前
从 prototype 到 V8,看懂 JavaScript 原型链
前端·javascript
ping某1 天前
专栏-null 和 undefined 到底是什么?
前端·javascript·后端
swipe1 天前
从 0 到 1 理解 React 虚拟列表:定高、不定高与 Canvas 版本完整拆解
前端·javascript·面试
铁皮饭盒1 天前
Bun执行python代码
前端·javascript·后端
zzzzzz3101 天前
当甲方说'logo放大的同时再缩小一点'时,我用 AI 把这个需求做出来了
javascript·css·程序员