JavaScript中&&和||执行短路求值,返回最后一个被求值的操作数:a&&b在a为falsy时返回a,否则返回b;a||b在a为truthy时返回a,否则返回b。

短路求值在 JavaScript 中到底怎么工作?
JavaScript 的 && 和 || 不返回布尔值,而是返回**最后一个被求值的操作数**。这意味着它们会从左到右执行,并在结果已确定时“停住”,不继续计算右边——这就是“短路”。
-
a && b:如果a是 falsy(如false、0、''、null、undefined、NaN),直接返回a,不执行b -
a || b:如果a是 truthy,直接返回a,不执行b
注意:0、''、null 等是 falsy,但它们本身是合法值——短路返回的就是它们,不是 false。
用 || 做默认值赋值时的常见陷阱
很多人用 const name = user.name || 'Anonymous' 设置默认值,这在 user.name === '' 或 0 时会意外覆盖原值。
- ✅ 安全写法(只在
undefined或null时回退):const name = user.name ?? 'Anonymous'(空值合并操作符) - ❌ 危险写法:
arr.length || 10—— 若arr.length === 0,会错误返回10 - ⚠️ 只有当你明确希望
falsy值触发默认行为时,才用||
const config = {
timeout: 0,
retries: null
};
// ❌ 错误预期:想保留 timeout: 0
console.log(config.timeout || 5000); // → 5000(因为 0 是 falsy)
// ✅ 正确方式:显式检查 undefined/null
console.log(config.timeout ?? 5000); // → 0
用 && 替代 if 语句的安全前提
condition && doSomething() 是常见简写,但它只适用于 doSomething() 没有副作用或你**确定它不会被意外调用**的场景。
立即学习“Java免费学习笔记(深入)”;
- ✅ 合理:仅用于触发无副作用的操作,如
loading && renderSpinner()(renderSpinner是纯渲染) - ❌ 危险:若
getData()有网络请求或状态变更,isValid && getData()在调试时可能被忽略——它不像if那样直观可断点 - ⚠️ 注意运算符优先级:
a && b || c等价于(a && b) || c,加括号更安全
let count = 0; const increment = () => ++count; // ❌ 看似简洁,但每次执行都会调用 increment(),即使 isReady 为 false? // 实际上不会:短路保证了只有 isReady 为 truthy 时才调用 const isReady = false; isReady && increment(); // → increment() 不执行,count 仍为 0 // ✅ 更清晰的写法(尤其团队协作中) if (isReady) increment();
链式短路:从深层对象取值时的实用技巧
访问嵌套属性如 user.profile.address.city 时,传统写法要层层判断;短路 + 逻辑组合能压缩代码,但需控制深度。
- ✅ 适合浅层(2–3 层):
user && user.profile && user.profile.city - ✅ 更现代替代:
user?.profile?.city(可选链),它比&&更精准(不会因中间值为0或''而中断) - ❌ 避免混用:
obj?.prop && obj.prop.method()——obj?.prop返回undefined,再&&就短路了,但语义混乱
const data = { user: { profile: null } };
// ❌ 混合写法难读且易错
console.log(data?.user?.profile && data.user.profile.city); // → undefined(短路生效,但掩盖了意图)
// ✅ 清晰分离:先安全取值,再判断使用
const city = data?.user?.profile?.city;
if (city) console.log('City:', city);
短路求值不是语法糖,是 JavaScript 执行模型的一部分;滥用它会让条件逻辑隐晦,尤其当 falsy 值本身具有业务意义时——这时候宁可多写一行 if,也别赌别人能立刻读懂你的 &&。









