迭代器模式
实现迭代器模式,顺序访问集合元素而不暴露内部结构
问题
实现迭代器模式,提供统一的方式遍历不同类型的集合。
解答
基本迭代器实现
// 创建一个简单的迭代器
function createIterator(items) {
let index = 0;
return {
next() {
if (index < items.length) {
return { value: items[index++], done: false };
}
return { value: undefined, done: true };
}
};
}
// 使用
const iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
实现可迭代对象
// 自定义可迭代对象,实现 Symbol.iterator
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...of 遍历
const range = new Range(1, 5);
for (const num of range) {
console.log(num); // 1, 2, 3, 4, 5
}
// 也可以使用展开运算符
console.log([...range]); // [1, 2, 3, 4, 5]
使用 Generator 简化实现
// Generator 函数自动返回迭代器
class Collection {
constructor() {
this.items = [];
}
add(item) {
this.items.push(item);
}
// 使用 Generator 实现迭代器
*[Symbol.iterator]() {
for (const item of this.items) {
yield item;
}
}
// 反向迭代器
*reverse() {
for (let i = this.items.length - 1; i >= 0; i--) {
yield this.items[i];
}
}
}
const collection = new Collection();
collection.add('a');
collection.add('b');
collection.add('c');
// 正向遍历
for (const item of collection) {
console.log(item); // a, b, c
}
// 反向遍历
for (const item of collection.reverse()) {
console.log(item); // c, b, a
}
树结构迭代器
// 二叉树节点
class TreeNode {
constructor(value, left = null, right = null) {
this.value = value;
this.left = left;
this.right = right;
}
}
// 二叉树,支持多种遍历方式
class BinaryTree {
constructor(root) {
this.root = root;
}
// 中序遍历(默认迭代器)
*[Symbol.iterator]() {
yield* this.inOrder(this.root);
}
*inOrder(node) {
if (node) {
yield* this.inOrder(node.left);
yield node.value;
yield* this.inOrder(node.right);
}
}
// 前序遍历
*preOrder(node = this.root) {
if (node) {
yield node.value;
yield* this.preOrder(node.left);
yield* this.preOrder(node.right);
}
}
// 后序遍历
*postOrder(node = this.root) {
if (node) {
yield* this.postOrder(node.left);
yield* this.postOrder(node.right);
yield node.value;
}
}
}
// 构建树: 1
// / \
// 2 3
const tree = new BinaryTree(
new TreeNode(1, new TreeNode(2), new TreeNode(3))
);
console.log([...tree]); // [2, 1, 3] 中序
console.log([...tree.preOrder()]); // [1, 2, 3] 前序
console.log([...tree.postOrder()]); // [2, 3, 1] 后序
惰性迭代器
// 惰性求值,按需计算
function* lazyMap(iterable, fn) {
for (const item of iterable) {
yield fn(item);
}
}
function* lazyFilter(iterable, predicate) {
for (const item of iterable) {
if (predicate(item)) {
yield item;
}
}
}
function* lazyTake(iterable, n) {
let count = 0;
for (const item of iterable) {
if (count++ >= n) break;
yield item;
}
}
// 链式调用,惰性求值
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const result = lazyTake(
lazyMap(
lazyFilter(numbers, x => x % 2 === 0), // 筛选偶数
x => x * 2 // 乘以 2
),
3 // 只取前 3 个
);
console.log([...result]); // [4, 8, 12]
关键点
- 迭代器对象需实现
next()方法,返回{ value, done } - 可迭代对象需实现
Symbol.iterator方法,返回迭代器 - Generator 函数是创建迭代器的简洁方式,
yield暂停执行并返回值 - 迭代器支持
for...of、展开运算符、Array.from()等语法 - 惰性迭代器按需计算,适合处理大数据集或无限序列
目录