60 秒回答模板

map、filter、reduce 都会遍历数组并接收回调,但语义不同:map 做一对一转换,返回同长度新数组;filter 做筛选,返回满足条件的子集;reduce 把数组折叠成任意累计结果,可以是数字、对象、Map 或数组。性能上它们都有回调调用成本,map/filter 会产生新数组,链式调用会多次遍历并产生中间数组。普通业务优先可读性,热点路径或大数据量场景再考虑合并遍历、for 循环或惰性处理。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

map 的语义

map 表达一对一映射,输入数组每个有效元素对应输出数组一个元素,长度通常不变。它适合字段转换、格式化和组件列表渲染前的数据映射。

02

filter 的语义

filter 表达保留或丢弃,回调返回 truthy 的元素会进入新数组。它不会改变元素本身,只改变集合规模。

03

reduce 的语义

reduce 表达累计,把数组按顺序折叠成一个结果。它能做求和、分组、索引构建、管道组合等,但初始值和 accumulator 类型要清楚。

04

性能来源

主要成本来自遍历次数、回调调用、闭包捕获和中间数组分配。filter(...).map(...) 可读性好,但会至少两次遍历并创建中间数组。

05

稀疏数组和副作用

这些方法通常跳过空槽,回调不会对不存在的索引执行。回调里修改原数组会让逻辑难以预测,应避免在高阶函数中混入副作用。

06

选型原则

能用 map/filter 表达清楚就不要硬写 reduce;reduce 适合确实需要累计状态的场景。性能敏感时可用一次 for 循环合并筛选和转换。

易错点

  • 不要只谈性能不谈语义。面试官首先想看你是否按意图选择 API。
  • 不要把 reduce 当万能替代。复杂 reduce 可能比 map/filter 更难维护。
  • 不要忘记 map/filter 返回新数组,但对象元素仍共享引用。
  • 不要忽略链式调用的中间数组和多次遍历成本。

面试官追问

reduce 一定比 map/filter 性能好吗?

不一定。reduce 也有回调成本,写法复杂还可能降低可读性。只有在确实能减少遍历和分配时才可能更好。

map 会改变原数组吗?

map 本身返回新数组,不修改原数组。但如果元素是对象,回调里修改对象属性会影响原数组中同一个对象引用。

reduce 为什么建议传初始值?

不传初始值时会用数组第一个有效元素作为 accumulator,空数组会报错,类型也不够稳定。传初始值能让返回类型和边界更明确。

链式调用什么时候需要优化?

当数组很大、链路很长、调用频繁或在渲染热点路径中时,可以合并遍历、缓存结果或改用更直接的循环。