2026-10-30 07:49:30
JavaScript实现迭代器的核心是遵循“可迭代协议”和“迭代器协议”,通过定义[Symbol.iterator]方法返回具备next()方法的迭代器对象,从而支持for...of循环和展开运算符(...)。以下是具体实现方法与关键要点:
一、迭代器协议与可迭代协议的实现示例:自定义Range对象
class MyRange { 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 }; } else { return { value: undefined, done: true }; } } }; }}const myNumbers = new MyRange(1, 5);for (const num of myNumbers) { console.log(num); // 输出:1, 2, 3, 4, 5}console.log([...myNumbers]); // 输出:[1, 2, 3, 4, 5]统一遍历接口
迭代器协议为所有可遍历数据结构(如数组、字符串、Set、Map及自定义对象)提供标准化接口,消除不同数据结构的遍历差异。
痛点解决:避免为不同数据结构编写碎片化遍历逻辑(如数组用for、对象用for...in、Set用forEach)。
惰性求值
仅在调用next()时计算当前值,适合处理大数据流或无限序列(如斐波那契数列),减少内存占用。
示例:若MyRange的end值极大或未定义,未遍历的部分不会提前计算。
生成器是迭代器的语法糖
生成器函数(function*)自动实现迭代器协议,通过yield暂停执行并返回值,简化手动维护状态和next()逻辑。
示例:function* simpleGenerator() { yield 1; yield 2; yield 3;}const gen = simpleGenerator();console.log(gen.next()); // { value: 1, done: false }console.log([...simpleGenerator()]); // [1, 2, 3]
选择依据
优先使用生成器:日常开发中,生成器代码更简洁、易读,适合大多数自定义迭代逻辑。
手动实现迭代器:需极致性能优化或精细控制迭代过程时(如复杂状态管理或非线性数据结构)。
特定遍历策略的迭代器
树的中序遍历:通过栈模拟递归,实现惰性求值。class InOrderTreeIterator { constructor(root) { this.stack = []; this._pushLeft(root); } _pushLeft(node) { while (node) { this.stack.push(node); node = node.left; } } next() { if (this.stack.length === 0) return { value: undefined, done: true }; const node = this.stack.pop(); this._pushLeft(node.right); return { value: node.value, done: false }; }}class BinaryTree { constructor(root) { this.root = root; } [Symbol.iterator]() { return new InOrderTreeIterator(this.root); }}console.log([...tree]); // 输出中序遍历结果
链式或组合迭代器
过滤迭代器:通过生成器函数实现惰性过滤。function* filterIterable(iterable, predicate) { for (const item of iterable) { if (predicate(item)) yield item; }}const evenNumbers = filterIterable([1, 2, 3, 4], n => n % 2 === 0);console.log([...evenNumbers]); // [2, 4]
无限序列的迭代器
斐波那契数列:生成器无限生成序列,避免内存溢出。function* fibonacciSequence() { let a = 0, b = 1; while (true) { yield a; [a, b] = [b, a + b]; }}const fib = fibonacciSequence();console.log(fib.next().value); // 0console.log(fib.next().value); // 1
通过理解并应用迭代器模式,可显著提升JavaScript代码的优雅性与效率,尤其在处理复杂遍历逻辑时优势明显。