JavaScript中Iterator实现树形菜单深度迭代的核心是通过Symbol.iterator协议支持for...of遍历,按深度优先顺序返回节点及层级信息,并可配置最大深度与过滤条件。

JavaScript 中 Iterator 实现树形菜单的深度迭代展开,核心是让树结构支持 for...of 遍历,并按深度优先顺序(即先遍历当前节点,再递归遍历子节点)逐个返回菜单项。这不需要手动写递归调用,而是通过自定义迭代器协议([Symbol.iterator]() 方法)封装遍历逻辑。
树节点类需实现 Symbol.iterator
每个菜单节点(如 MenuItem)应具备迭代能力。通常让节点自身可被遍历,返回包括自己及全部后代的扁平序列:
- 定义
[Symbol.iterator]()方法,返回一个遵循迭代器协议的对象(含next()方法) - 内部用栈模拟深度优先遍历:先压入当前节点,每次
next()弹出一个节点,将其子节点逆序压入(保证左→右顺序) - 避免递归调用栈溢出,栈式实现更可控、易中断
用生成器函数简化迭代器编写
相比手写迭代器对象,function* 生成器天然符合迭代器协议,代码更简洁、语义更清晰:
- 在节点类中定义
*[Symbol.iterator](),用yield依次产出当前节点、再递归yield*子树 -
yield*会自动委托子迭代器,天然支持深度优先展开 - 示例:
yield this; if (this.children) for (const child of this.children) yield* child;
支持带层级信息的深度遍历
实际菜单渲染常需知道当前节点深度(如缩进、CSS class)。可在迭代时携带层级参数:
立即学习“Java免费学习笔记(深入)”;
- 生成器接受
depth = 0参数,每次递归调用时传入depth + 1 - 不直接
yield this,而是yield { node: this, depth },返回结构化数据 - 这样
for...of遍历时能同时获取节点和其嵌套层级,方便模板渲染
可中断与条件过滤的扩展设计
真实场景中可能只需展开到某一层、或跳过禁用项。迭代器可设计为可配置:
- 接收选项对象,如
{ maxDepth: 2, filter: node => node.enabled } - 在生成器中判断
depth >= maxDepth则跳过子节点递归 -
filter在yield前校验,被过滤节点及其子树均不出现 - 保持迭代器纯函数特性:不修改原树,只控制输出流
不复杂但容易忽略的是:Iterator 不负责渲染,只提供有序数据流;配合 for...of 或展开运算符([...menu])就能自然接入列表生成逻辑。关键在把“遍历意图”从调用方转移到数据结构本身。


















