流程控制与递归在JavaScript中协同工作:分支结构决策路径,递归深入处理嵌套结构;if/else控制入口与终止,switch管理多类型递归行为,循环驱动批量子项递归,三元表达式简化浅层二选一逻辑。

流程控制和递归在 JavaScript 中不是对立关系,而是可以自然协同的工具:流程控制决定“走哪条路”,递归负责“把这条路走到底”。关键在于用分支结构做决策、用递归处理重复嵌套结构,两者配合能清晰表达复杂逻辑,比如树遍历、权限校验、表达式解析等场景。
用 if/else 控制递归入口和终止条件
递归函数必须有明确的退出路径,而 if 语句是最直接的实现方式。它既判断是否继续递归,也决定当前层级该执行哪一分支逻辑。
- 基线条件(base case)通常写在 if 分支开头,比如
if (node === null || depth > MAX_DEPTH) return; - 多分支场景下,可用 if-else if-else 区分不同节点类型:普通节点、叶子节点、错误节点、特殊标记节点
- 避免把所有逻辑塞进递归调用里——先用分支理清当前层状态,再决定是否递归、向哪一层递归、传什么参数
用 switch 管理多种递归行为模式
当递归处理的对象存在明确分类(如 AST 节点类型、配置项类型、API 响应状态),switch 比长串 if 更易读、更易维护。
- 例如解析 JSON Schema:根据
schema.type切换处理逻辑——"object"时递归遍历properties,"array"时递归检查items,"string"时只做正则校验 - 每个 case 内可独立决定是否递归、递归几次、是否并行或串行调用
- default 分支建议保留,用于捕获未定义类型,防止静默失败
循环 + 递归组合处理聚合型结构
单纯递归适合深度优先,但遇到需批量处理子项(如数组元素、对象属性、DOM 子节点)时,常配合 for 或 for...of 循环驱动递归调用。
立即学习“Java免费学习笔记(深入)”;
- 典型写法:
for (const child of node.children) { processNode(child, depth + 1); } - 注意避免在循环中修改正在遍历的集合(如 push 新子节点),否则可能造成无限递归或跳过节点
- 若需控制并发或顺序,可在循环内加 await、使用 Promise.all 或队列机制,但递归本身仍保持单次调用语义
用三元表达式简化浅层分支递归
对于二选一、逻辑简单、无副作用的递归场景(如查找、计数、扁平化),三元表达式能让代码更紧凑,且天然契合递归的“条件→结果”结构。
- 示例:计算嵌套数组总长度
const deepLength = arr => Array.isArray(arr) ? arr.reduce((sum, item) => sum + deepLength(item), 0) : 1; - 不适用于含副作用操作(如 console.log、DOM 修改),因为三元表达式难以插入中间步骤
- 深度较大时仍需考虑栈限制,必要时改用迭代+栈模拟


















