flat()和flatMap()是ES2019引入的原生数组方法:flat()按指定深度展开嵌套数组,支持depth参数(默认1,Infinity可完全扁平);flatMap()先映射再扁平一层,等价于map().flat(1),适合“生成并合并”场景。

直接用 flat() 和 flatMap() 是处理嵌套数组最简洁、可靠的方式,无需手写递归或嵌套 reduce,语义清晰且性能更好。
flat():专注“展开”,按需控制深度
当你只需要把已有的嵌套结构压平,不改变元素本身,flat() 就是最自然的选择。它接受一个可选参数 depth,决定展开几层:
-
[1, [2, 3], [4, [5]]].flat()→[1, 2, 3, 4, [5]](默认只展一层) -
[1, [2, [3, [4]]]].flat(2)→[1, 2, 3, [4]](明确控制展两层) -
[1, [2, [3]]].flat(Infinity)→[1, 2, 3](彻底扁平,无视嵌套层数)
注意:flat() 会跳过数组中的空槽(如 [1, , 3]),但不会过滤 undefined 或 null 值。
flatMap():先变换,再展平一层
flatMap() 适合“一边处理每个元素,一边合并结果”的场景。它等价于 map().flat(1),但只执行一次遍历,更高效:
-
[{items: [1,2]}, {items: [3,4]}].flatMap(d => d.items)→[1, 2, 3, 4] -
[1, 2, 3].flatMap(x => x % 2 === 0 ? [x, x * 2] : [])→[2, 4](偶数复制,奇数过滤) - 如果映射函数返回非数组值(如字符串或数字),flatMap() 会自动包装成单元素数组再展平,不会报错。
什么时候该选哪个?
关键看操作意图:
- 只要“结构变平”,不改数据 → 用 flat()
- 既要“生成新内容”,又要“合并成一维” → 用 flatMap()
- 需要完全扁平化任意深度嵌套 → flat(Infinity) 是唯一原生解
- 处理 API 返回的
Array<{data: Array<T>}>类型响应 → flatMap() 几乎是标配
兼容性与替代提醒
这两个方法在现代浏览器和 Node.js(≥12)中均原生支持,但不兼容 IE。若需支持旧环境,可用 Babel 转译,或手动 fallback:
-
flat()可用reduce((acc, val) => acc.concat(Array.isArray(val) ? val : [val]), [])模拟(仅限 depth=1) -
flatMap()可拆为map().flat(1),但会多一次遍历,不推荐长期使用

















