flatMap本身不自动过滤null,仅跳过空数组;若映射函数返回null或undefined会抛TypeError,正确做法是返回空数组[]而非null。
很多人以为 flatMap 会像 map + filter 那样自动丢掉 null 或 undefined,其实不会。它的行为是:对每个元素调用映射函数,得到一个数组,再把所有数组「扁平化一层」拼起来。关键点在于:如果映射函数返回空数组 [],它就不会贡献任何元素;但若返回 null 或 undefined,就会直接报错——因为扁平化时试图展开非数组值。
[]
item => item && transform(item) —— 这可能返回 null,导致 flatMap 报 TypeError: Cannot convert undefined or null to object
[null] 或 [undefined] 会被保留为真实元素,不是“过滤”核心逻辑是「有数据才返回单元素数组,否则返回空数组」。常见场景比如处理可能为空的对象字段、异步结果未就绪、或 API 返回了稀疏数组。
arr.flatMap(item => item.id ? [{ id: item.id, name: item.name }] : [])
item.tags 可能为 null):arr.flatMap(item => Array.isArray(item.tags) ? item.tags : [])
arr.flatMap(n => n > 0 ? [n * 2] : []) —— 负数和 0 被过滤,正数翻倍flatMap 等价于 map 后接 flat(1),但两者在错误处理上不同:前者在映射阶段就要求返回数组,后者允许 map 返回任意值(flat 再统一处理)。这意味着你不能依赖 flatMap 容忍 null 返回值。
[1, 2, 3].flatMap(x => x === 2 ? null : [x]) → 报错[1, 2, 3].map(x => x === 2 ? null : [x]).flat(1) → 得到 [1, 3](因为 null 被 flat 当作“空槽”忽略)null 来过滤,得用 map + flat(1),但语义不如显式返回 [] 清晰用 flatMap 过滤的写法看似简洁,但如果映射逻辑稍复杂(比如含异步、多重判断),强行塞进一个返回数组的函数里反而难读。此时更推荐先 filter 再 map,尤其当过滤条件和映射逻辑不强相关时。
arr.filter(Boolean).map(transform) 比 arr.flatMap(x => x ? [transform(x)] : []) 更易扫读flatMap 对 NaN、0、"" 等 falsy 值不做特殊处理,是否过滤它们必须显式写条件