?? 仅在操作数为 null 或 undefined 时取默认值,|| 在任意 falsy 值(如 0、''、false)时均触发;前者语义精准,适用于保留合法 falsy 值的场景,后者语义宽泛,常用于统一兜底。

双问号(??)和逻辑或(||)都用于提供默认值,但它们的判断依据完全不同:前者只在值为 null 或 undefined 时生效;后者在值为任意“falsy”值(如 0、''、false、null、undefined、NaN)时都会触发默认值。
判断条件不同:null/undefined vs 所有 falsy 值
这是最核心的区别:
-
??只在左侧操作数严格等于null或undefined时,才返回右侧操作数 -
||只要左侧是任何 falsy 值(包括0、空字符串''、false等),就返回右侧操作数
例如:
0 ?? 42 // 0(因为 0 不是 null/undefined) 0 || 42 // 42(因为 0 是 falsy) '' ?? 'hi' // ''(空字符串不是 null/undefined) '' || 'hi' // 'hi'(空字符串是 falsy) false ?? true // false false || true // true null ?? 'fallback' // 'fallback' null || 'fallback' // 'fallback'
适用场景不同:语义更精准 vs 习惯性兜底
选择哪个运算符,取决于你真正想“容错”的范围:
立即学习“Java免费学习笔记(深入)”;
- 用
??当你只想处理“缺失值”(即变量根本没定义或被显式设为null),而希望保留合法的0、false、''等值 - 用
||当你希望对所有“无意义”的值统一兜底,比如表单输入为空时给默认提示,或数字为 0 时当作未填写
典型例子:
配置项默认值 —— 若后端可能返回 { count: 0 },且 0 是有效业务值,就该用 config.count ?? 10;若用 config.count || 10,0 就会被错误替换成 10。
结合使用与优先级注意
两者可混合使用,但要注意运算符优先级:?? 和 || 优先级相同,**从左到右执行**,且不允许不加括号混用(会报语法错误):
-
a ?? b || c❌ 语法错误(禁止连写) -
(a ?? b) || c✅ 先空值合并,再逻辑或 -
a ?? (b || c)✅ 先逻辑或,结果再参与空值合并
推荐明确加括号,避免歧义。多数情况下,一个表达式里只用一种默认策略更清晰。
兼容性与替代写法
?? 是 ES2020 新增特性,旧环境(如 IE、早期 Node.js)不支持。可用 Babel 转译,或手动降级:
- 替代写法:
(a !== null && a !== undefined) ? a : b - 更简洁的兼容写法:
a == null ? b : a(利用null == undefined且二者是仅有的== null的值)
而 || 兼容所有 JavaScript 环境,历史悠久,但语义较宽泛。










