Iterator.prototype.flatMap()

基准线 2025
新推出

自 ⁨2025 年 3 月⁩ 起,此功能可在最新的设备和浏览器版本上使用。此功能可能在旧设备或浏览器上无法正常工作。

flatMap() 方法用于 Iterator 实例,它会返回一个新的 迭代器辅助对象,该对象会遍历原始迭代器中的每个元素,运行一个映射函数,并生成映射函数返回的元素(这些元素包含在另一个迭代器或可迭代对象中)。

语法

js
flatMap(callbackFn)

参数

callbackFn

一个要为迭代器生成的每个元素执行的函数。它应该返回一个生成 flatMap() 要生成的元素的迭代器或可迭代对象。请注意,与 Array.prototype.flatMap() 不同,你不能返回单个非迭代器/可迭代值。该函数使用以下参数进行调用

element

数组中正在处理的当前元素。

index

数组中正在处理的当前元素的索引。

返回值

一个新的 迭代器辅助对象。当迭代器辅助对象的 next() 方法被首次调用时,它会对底层迭代器生成的第一个元素调用 callbackFn,然后返回的值(它应该是一个迭代器或可迭代对象)会由迭代器辅助对象逐个生成(类似于 yield*)。当 callbackFn 返回的元素生成完毕后,会从底层迭代器获取下一个元素。当底层迭代器完成时,迭代器辅助对象也会完成(next() 方法会生成 { value: undefined, done: true })。

异常

TypeError

如果 callbackFn 返回一个非迭代器/可迭代值或字符串原始类型,则会抛出此错误。

描述

flatMap 接受 callbackFn 的两种返回类型:迭代器或可迭代对象。它们的处理方式与 Iterator.from() 相同:如果返回值是可迭代的,则调用 [Symbol.iterator]() 方法并使用其返回值;否则,将返回值视为迭代器并调用其 next() 方法。

js
[1, 2, 3]
  .values()
  .flatMap((x) => {
    let itDone = false;
    const it = {
      next() {
        if (itDone) {
          return { value: undefined, done: true };
        }
        itDone = true;
        return { value: x, done: false };
      },
    };
    switch (x) {
      case 1:
        // An iterable that's not an iterator
        return { [Symbol.iterator]: () => it };
      case 2:
        // An iterator that's not an iterable
        return it;
      case 3:
        // An iterable iterator is treated as an iterable
        return {
          ...it,
          [Symbol.iterator]() {
            console.log("Symbol.iterator called");
            return it;
          },
        };
      default:
        return undefined;
    }
  })
  .toArray();
// Logs "Symbol.iterator called"
// Returns [1, 2, 3]

示例

合并 Map

以下示例将两个 Map 对象合并为一个

js
const map1 = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);
const map2 = new Map([
  ["d", 4],
  ["e", 5],
  ["f", 6],
]);

const merged = new Map([map1, map2].values().flatMap((x) => x));
console.log(merged.get("a")); // 1
console.log(merged.get("e")); // 5

这可以避免创建 Map 内容的任何临时副本。请注意,数组 [map1, map2] 必须首先转换为迭代器(使用 Array.prototype.values()),因为 Array.prototype.flatMap() 仅展开数组,而不展开可迭代对象。

js
new Map([map1, map2].flatMap((x) => x)); // Map(1) {undefined => undefined}

返回字符串

字符串是可迭代的,但 flatMap() 会专门拒绝 callbackFn 返回的字符串原始类型,这是因为按码点进行迭代的行为通常不是你想要的。

js
[1, 2, 3]
  .values()
  .flatMap((x) => String(x))
  .toArray(); // TypeError: Iterator.prototype.flatMap called on non-object

你可能希望将其包装在数组中,以便整个字符串作为一个整体生成

js
[1, 2, 3]
  .values()
  .flatMap((x) => [String(x)])
  .toArray(); // ['1', '2', '3']

或者,如果你想要按码点迭代的行为,可以使用 Iterator.from() 将其转换为一个正确的迭代器

js
[1, 2, 3]
  .values()
  .flatMap((x) => Iterator.from(String(x * 10)))
  .toArray();
// ['1', '0', '2', '0', '3', '0']

规范

规范
ECMAScript® 2026 语言规范
# sec-iterator.prototype.flatmap

浏览器兼容性

另见