空值合并运算符(??)仅在左侧为null或undefined时使用右侧默认值,不将0、false、''视为“空”,与||有本质区别;适用于变量合法取值包含假值但仅缺失时fallback的场景。

空值合并运算符(??)只在左侧为 null 或 undefined 时才使用右侧默认值,它不会把 0、false、''(空字符串)当作“空”来处理——这点和逻辑或 || 有本质区别。
什么时候该用 ?? 而不是 ||
当你的变量可能合法地取到 0、false、'',但你只想在真正缺失(null/undefined)时 fallback,默认值才适用 ??。
-
const count = response?.data?.count ?? 10;—— 如果 API 返回{data: {count: 0}},结果是0,不是10 -
const isActive = user?.active ?? true;—— 若user.active是false,仍保留false;只有字段根本不存在或为null才用true - 误用
||:user?.age || 25在age === 0时也会 fallback 到25,这通常不符合业务语义
?? 的优先级和链式写法要注意括号
?? 优先级低于 && 和 ||,直接混用会出错。想组合判断时必须加括号,否则 JS 会按默认优先级解析。
- ❌ 错误:
a ?? b && c等价于(a ?? b) && c,不是你想表达的 “a 为空则取 (b && c)” - ✅ 正确:
a ?? (b && c)或(a ?? b) && c,按需明确分组 - 链式默认值安全:
obj?.x?.y ?? obj?.fallback ?? 'default'—— 可连续??,从左到右第一个非 null/undefined 值即返回
和可选链 ?. 搭配是最常见也最易出错的场景
很多人以为 obj?.prop ?? 'default' 能覆盖所有“访问不到”的情况,但它其实只防 obj 为 null/undefined,不防 obj 存在但 prop 是 undefined —— 这恰恰是 ?? 生效的条件。
立即学习“Java免费学习笔记(深入)”;
- ✅ 安全组合:
user?.profile?.name ?? 'Anonymous'—— 即使user或profile是null/undefined,也不会报错;若name是undefined,就用默认值 - ⚠️ 注意:如果
user.profile是一个对象,但name属性压根没定义(in检查为false),读出来就是undefined,此时??依然生效 - ❌ 不要写成
user?.profile?.name || 'Anonymous'—— 当name === ''或0,你会意外丢失原始值
真正容易被忽略的是嵌套结构中某一层存在但值为 undefined 的情况:它既不是运行时错误(所以 ?. 不拦截),又触发 ??,但开发者常误以为那是“数据没传过来”,其实只是后端显式设了 undefined(虽然 JSON 里没有 undefined,但 JS runtime 中可能出现)。遇到奇怪的默认值覆盖,先 console.log 看清原始值类型。










