Iterator

Iterator 是通过 next() 按次产出值的对象,是可迭代对象的执行结果。

#type / concept #status / growing #resource / javascript #resource / ecmascript

[!info] related notes

Iterator

一句话定义

Iterator 是一个带 next() 方法的对象,每次调用 next() 返回 { value, done },是逐步产出值的协议。

核心机制 / Symbol.iterator 协议

  1. 可迭代对象(Array、Map、Set、String 等)实现 Symbol.iterator 方法。
  2. 调用 obj[Symbol.iterator]() 返回一个迭代器对象。
  3. 迭代器对象有 next() 方法,返回 { value, done }
  4. done: true 之后的调用继续返回 { value: undefined, done: true }
const arr = ['a', 'b', 'c'];
const iter = arr[Symbol.iterator]();

iter.next(); // { value: 'a', done: false }
iter.next(); // { value: 'b', done: false }
iter.next(); // { value: 'c', done: false }
iter.next(); // { value: undefined, done: true }

for…of 消费

// for...of 内部自动调用 Symbol.iterator
for (const item of ['x', 'y', 'z']) {
  console.log(item); // x, y, z
}

// Map 迭代
const map = new Map([['a', 1], ['b', 2]]);
for (const [key, value] of map) {
  console.log(key, value);
}

// String 迭代
for (const char of 'hello') {
  console.log(char); // h, e, l, l, o
}

自定义迭代器

class Range {
  constructor(start, end) {
    this.start = start;
    this.end = end;
  }

  [Symbol.iterator]() {
    let current = this.start;
    const end = this.end;
    return {
      next() {
        if (current <= end) {
          return { value: current++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
}

for (const n of new Range(1, 5)) {
  console.log(n); // 1, 2, 3, 4, 5
}

// 展开运算符也消费迭代器
const nums = [...new Range(1, 3)]; // [1, 2, 3]

Generator 作为迭代器

function* range(start, end) {
  for (let i = start; i <= end; i++) {
    yield i;
  }
}

// Generator 自带 Symbol.iterator,既可迭代又可单独当迭代器
const gen = range(1, 3);
gen.next(); // { value: 1, done: false }
gen.next(); // { value: 2, done: false }
gen.next(); // { value: 3, done: false }
gen.next(); // { value: undefined, done: true }

// 也可以直接 for...of
for (const n of range(1, 5)) {
  console.log(n);
}

实际使用场景

// 无限序列
function* fibonacci() {
  let a = 0, b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();
fib.next().value; // 0
fib.next().value; // 1
fib.next().value; // 1
fib.next().value; // 2

// 惰性处理大数据集
function* filter(iterable, predicate) {
  for (const item of iterable) {
    if (predicate(item)) yield item;
  }
}

与 forEach 的区别

维度Iterator / for…offorEach
中途退出break / return 可以不行(只能用 try/catch 绕过)
惰性求值支持(Generator)不支持,立即遍历全部
适用对象所有可迭代对象只有 Array、Map、Set
异步for await...of不支持

边界与常见误解

  • Iterator 通常是一次性的:遍历完就结束,不能重置。需要重新调用 Symbol.iterator 获取新迭代器。
  • Object 不是可迭代对象:普通 {} 没有 Symbol.iterator,不能直接 for...of。需要 Object.keys/values/entries
  • Iterator 不等于 Iterable:如果一个对象只有 next() 但没有 [Symbol.iterator](),它不能被 for...of 消费。实现 [Symbol.iterator]() { return this; } 可以让它同时是两者。
  • 展开运算符 ...、解构赋值、Array.from 都消费迭代器
创建于 2026/4/7 更新于 2026/5/27