如何循环遍历JavaScript对象中任意深度的嵌套list子元素
不定深度嵌套对象遍历方案
固定层数的嵌套循环仅能覆盖预先设定好的深度,既会在浅层级场景下产生冗余代码,也无法覆盖超过预设深度的嵌套结构,针对随机深度的嵌套场景,优先使用递归或手动维护遍历栈/队列的方式实现通用遍历。
注意:你提供的示例静态循环代码存在拼写错误,属性名
lisit为笔误,正确应为list,该错误会直接导致代码运行报错。
方案1:递归深度优先遍历(最简洁实现)
核心逻辑是封装通用遍历函数,每遍历到一个节点时,先执行节点处理逻辑,再判断节点是否存在非空的list子属性,若存在则将子list传入同一个遍历函数继续向下遍历,无list属性时自动终止当前分支遍历。
代码实现:
function traverse(currentList) { // 边界判定:当前无有效可遍历对象时直接终止 if (!currentList || typeof currentList !== 'object') return for (const key in currentList) { const currentNode = currentList[key] // 此处编写节点处理逻辑,示例为打印节点 console.log(currentNode) // 存在子list则递归进入下一层遍历 if (currentNode.list && typeof currentNode.list === 'object') { traverse(currentNode.list) } } } // 传入顶层list启动遍历 traverse(menu.list)
该方案优势:
- 无需提前预知嵌套深度,可覆盖任意层级的嵌套节点
- 无冗余循环,遇到无
list属性的节点会自动终止当前分支 - 代码结构简单,后续调整节点处理逻辑仅需修改遍历函数内的对应代码即可
方案2:非递归遍历(避免极端深嵌套栈溢出)
如果业务场景可能出现上千层的极端深嵌套,递归可能触发JS调用栈上限报错,此时可以手动维护遍历栈实现相同的遍历逻辑,没有栈溢出风险:
function traverseNoRecursion(rootList) { if (!rootList || typeof rootList !== 'object') return // 初始化遍历栈,压入顶层list const stack = [rootList] while (stack.length) { const currentList = stack.pop() for (const key in currentList) { const currentNode = currentList[key] // 节点处理逻辑 console.log(currentNode) // 子list压入栈等待后续遍历 if (currentNode.list && typeof currentNode.list === 'object') { stack.push(currentNode.list) } } } } // 启动遍历 traverseNoRecursion(menu.list)
如果需要按从上到下的层级顺序遍历(广度优先),只需要把栈替换为队列,将出栈方法pop()替换为出队方法shift()即可,其余逻辑不变。
内容的提问来源于stack exchange,提问作者Irvan Hilmi
相关产品推荐
相关产品推荐

