可选链操作符?.用于安全访问深层属性,遇null/undefined自动返回undefined不报错;需配合??提供默认值,不可用于赋值或单独解构。

直接用 ?. 替代普通点号 .,就能在任意一层为 null 或 undefined 时自动停止访问、返回 undefined,不报错。
访问对象深层属性
比如要读取 user.profile.address.city,传统写法需层层判断:
user && user.profile && user.profile.address && user.profile.address.city
用可选链只需一行:
user?.profile?.address?.city- 只要
user、profile或address中任一为null/undefined,整个表达式立刻返回undefined - 它只对
null和undefined短路,不会误判0、false、''等合法值
安全读取数组首个元素的属性
数组可能为空,或首项为 null/undefined,此时直接写 arr[0].name 会报错。
- 正确写法是
arr?.[0]?.name:先确保arr存在,再确保arr[0]存在,最后取name - 错误写法如
arr?.[0].name(漏掉第二个?)或a?.[0].foo(语法非法)都不可靠 - 若数组本身也可能为
null,必须写成arr?.[0]?.name,不能省略任一?
配合空值合并运算符 ?? 提供默认值
?. 返回的是 undefined,业务中通常需要兜底值,这时必须用 ??,而不是 ||:
-
const city = user?.profile?.address?.city ?? '未知城市'—— 只有真正为null/undefined才替换 -
user?.profile?.address?.city || '未知城市'是错的:如果city是0、false或'',也会被替换成兜底值 -
??是惰性求值,右侧表达式仅在左侧为null/undefined时执行,适合调用无副作用的函数
注意不能用的地方
?. 是读取操作的安全工具,不是万能补丁:
- 不能用于赋值左侧:
user?.profile = {}是语法错误 - 不能单独用于解构:
const { name } = user?.profile仍可能报错;应写成const { name } = user?.profile ?? {} - 如果某层按设计“必须存在”,却还加
?.,说明数据契约或类型定义有问题,该修源头,而非掩盖 - 它不校验结构合理性,也不处理异步加载中的竞态问题,需结合加载状态做条件渲染


















