避免缩进地狱的核心是重构控制流:用卫语句提前返回、拆解条件为语义化函数、统一使用花括号、以数据结构替代分支链。

避免 JS 条件分支中的缩进地狱,核心是让主逻辑“浮上来”,把干扰项“请出去”。不是靠更小心地缩进,而是重构控制流本身。
用卫语句提前返回
把校验、拦截、边界情况写在最前面,满足即 return,不继续嵌套。主业务逻辑自然落在顶层缩进,一眼可见。
- 不要写:if (user) { if (user.isActive) { if (user.hasPermission) { /* 主逻辑 */ } } }
- 要写:if (!user) return null;
if (!user.isActive) return 'inactive';
if (!user.hasPermission) throw new Error('no access');
// ✅ 主逻辑直接写在这里,无缩进
拆解复杂条件为语义化函数
一个 if 里堆着 order && order.items.length > 0 && order.status === 'paid' && !order.isRefunded,既难读又难复用。把它抽成独立函数,名字就是它的意图。
- 提取:function isValidActiveOrder(order) { return order && order.items?.length && order.status === 'paid' && !order.isRefunded; }
- 使用:if (isValidActiveOrder(order)) { ... } —— 条件清晰,后续加日志或开关也只改一处
统一加花括号,杜绝悬挂 else
哪怕只有一行语句,也写 { }。这不是啰嗦,是切断歧义链:else 永远绑定到最近的 if,而缩进会骗人,大括号不会。
- 错:if (x) if (y) doA(); else doB();(else 实际属于 if(y),不是 if(x))
- 对:if (x) { if (y) { doA(); } else { doB(); } } 或更推荐——用卫语句代替整个嵌套
用数据结构替代长 switch/if-else 链
当分支基于固定键值(如状态码、角色、类型),优先考虑对象映射或 Map,而不是层层 if。
- 例如运费计算:const feeMap = { admin: 0, vip: 5, user: 10 }; return feeMap[role] ?? 15;
- 比 5 个 else-if 更易查、易增、易测试,也彻底消除了缩进











