可选链(?.)和空值合并(??)可替代层层判断,安全访问深层属性并精准设置默认值:user?.profile?.address?.city ?? '未知',避免因null/undefined报错,且保留0、false等假值。

直接用可选链(?.)和空值合并(??)替代层层判断,能跳过中间对象是否存在检查,避免冗余的 if 或三元嵌套。
用 ?. 安全访问深层属性,跳过中间 null/undefined
传统写法需逐级判断对象是否为空:
if (user && user.profile && user.profile.address) {
console.log(user.profile.address.city);
}
用 ?. 一行搞定,遇到 null 或 undefined 自动短路返回 undefined,不报错:
-
user?.profile?.address?.city—— 安全读取,无需提前校验中间层 - 支持方法调用:
obj?.method?.(),若obj或method为 null/undefined,不执行也不报错 - 搭配数组索引也安全:
list?.[0]?.name
用 ?? 设置默认值,只在真值为空时生效
?? 与 || 的关键区别:它只在左侧为 null 或 undefined 时才用右侧,默认值更精准:
-
const name = user?.name ?? '匿名用户'—— 若user不存在或user.name是null/undefined,才用默认值;但''、0、false这类假值仍会被保留 - 对比
||:user.name || '匿名用户'在name为''或0时也会触发默认,容易误覆盖 - 可链式组合:
config?.theme?.color ?? 'blue'
组合使用 ?. 和 ?? 消除整个中间判断链
常见场景:从 API 响应中取一个可能多层嵌套、且某层可能缺失的字段,并给兜底值:
- 旧写法要写 4–5 行,含 if、临时变量、else 分支
- 新写法一行解决:
const avatar = userData?.settings?.ui?.avatarUrl ?? '/default-avatar.png' - 即使
userData、settings、ui中任一为null或undefined,表达式仍安全执行,最终得到字符串
注意边界:?. 不适用于动态属性名或计算属性
?. 只支持静态属性访问,不能用于方括号内含变量的场景(除非配合 ?? 做兜底):
- ✅ 正确:
obj?.['key'](字符串字面量) - ❌ 错误:
obj?.[dynamicKey](会语法报错) - ✅ 替代方案:
obj && obj[dynamicKey] ?? 'default',或封装成工具函数











