可选链操作符(?.)仅防止属性访问时崩溃,不保证结果可用;需与空值合并运算符(??)配合提供默认值,并辅以类型校验或早期返回才能真正安全。

可选链操作符(?.)不能完全避免空值错误,它只在访问属性/方法时跳过 null 或 undefined,但后续逻辑仍可能因返回 undefined 引发新问题。
什么时候 ?. 会静默失败却埋下隐患
它只保护「点操作」本身不报错,不保证结果可用。比如 obj?.user?.name 返回 undefined 后,若直接传给需要字符串的函数,运行时仍会出错。
-
console.log(user?.profile?.avatar?.src)输出undefined,但如果你紧接着做.split('/'),就会触发TypeError: Cannot read property 'split' of undefined - 数组访问用
arr?.[0]?.id,若arr是空数组,结果是undefined,不是你想的“安全默认值” -
func?.()不会报错,但如果func本该返回对象,而你又链式调用func?.().data?.items,中间任意一环为null/undefined都会让整条链坍塌为undefined
?. 和 ?? 必须配合使用才真正安全
可选链负责“不崩”,空值合并运算符 ?? 负责“兜底”。两者组合才能覆盖读取 + 使用两个阶段。
- 错误写法:
const name = user?.info?.name; console.log(name.toUpperCase());—— 若name是undefined,toUpperCase报错 - 正确写法:
const name = user?.info?.name ?? 'Anonymous'; console.log(name.toUpperCase()); - 函数调用后取属性也一样:
getData()?.items?.[0]?.id ?? 0,比单独用?.多一层防御
哪些场景下 ?. 根本不起作用
它只对属性访问、方法调用、数组索引有效,对其他操作无能为力。
立即学习“Java免费学习笔记(深入)”;
- 不能用于赋值:
obj?.name = 'Alice'语法错误,?.只出现在读取侧 - 不能跳过
undefined的函数参数:doSomething(obj?.value)中,obj?.value是undefined,但doSomething仍会被调用,错误由函数内部抛出 - 不能替代类型检查:若
user?.age是字符串"25",而你需要数字,?.不会帮你转类型或校验格式 - 不处理异步空值:
await api.getUser()?.then(...)——?.在await前就执行了,如果api.getUser()返回undefined,undefined.then依然报错
真正安全的空值处理,靠的是分层意识:用 ?. 防止访问崩溃,用 ?? 提供默认值,再根据业务需要加类型校验或早期返回。漏掉任何一层,都可能在某个边缘 case 里突然炸开。










