&& 左边应放“大概率 false”的条件,因其一遇 false(如 null、undefined、0、"")即短路,跳过右侧耗时操作;|| 左边应放“大概率 true”的条件,因其一遇 true 即返回,跳过右侧兜底逻辑,二者均需规避隐式转换陷阱并控制嵌套深度以保障可读性与性能。

&& 和 || 的短路特性本身不提升「单次」性能,但能跳过右侧耗时操作——前提是把轻量、高确定性条件放左边,把可能抛错或慢的操作放右边。否则只是徒增可读性负担。
为什么 && 左边该放「大概率 false」的条件
因为 && 一见左边是 false(如 null、undefined、0、""、[] 在布尔上下文中为假),就立刻停住,不再执行右边。典型场景:
- 防空访问:
obj && obj.name && obj.name.length > 5—— 第一个obj为null,后面两个子表达式根本不会求值 - 避免昂贵调用:
isFeatureEnabled() && fetchUserData()—— 功能没开,fetchUserData不会发请求 - 注意陷阱:
0 && doSomething()会短路,但0是合法数值,别误以为“只要非空就行”
为什么 || 左边该放「大概率 true」的条件
|| 一见左边是 true(非零、非空、非 null、非 undefined),就直接返回它,跳过右边。常用于默认值和兜底逻辑:
- 设默认值:
config.timeout || 3000——config.timeout有值就用,没有才取3000 - 防空方法调用:
user && user.getProfile() || getDefaultProfile()——user存在且getProfile()返回真值才用它,否则 fallback - 警惕隐式转换:
0 || 10返回10,但0是有效配置值,此时该用userConfig?.timeout ?? 3000
哪些操作放右边才真正被跳过
只有「执行时才会触发副作用」的操作,才能从短路中受益。以下右侧内容可被跳过:
- 函数调用:
validateInput() && saveToDB()中,saveToDB可跳过 - DOM 查询:
el && el.querySelector('.item')中,查不到el就不查子节点 - 正则匹配:
text && /error/i.test(text)中,text为空时正则不运行 - 不能跳过的:
el = document.getElementById('x')这类赋值语句写在右边,依然会执行(因为它是左侧表达式的一部分);短路只跳过「作为操作数的整个表达式」,不跳过赋值本身
嵌套太多 or 复杂条件时,短路反而拖慢性能
V8 等现代引擎对简单短路优化很好,但遇到 a && b && c && d && expensiveFn() 这种长链,JIT 编译器可能放弃内联,实际比拆成清晰的 if 分支还慢。实测表明:
- 超过 3 层
&&或||,可读性和性能双双下降 - 含副作用的短路(如
flag && apiCall())会让调试困难,IDE 常报「Expression has no effect」 - 真正高频路径上,优先封装成独立函数,再由
if显式控制调用时机
expensiveFn 即便没被调用,只要出现在作用域里,它的闭包环境仍被保留。


















