可选链操作符?.是安全访问嵌套属性的语法糖,仅在左侧为null或undefined时返回undefined而不报错;适用于API响应、动态表单、未挂载DOM等场景;支持属性访问、方法调用、数组索引,但不可用于赋值、delete或解决ReferenceError。

可选链操作符 ?. 是什么?
它是一个安全访问嵌套属性的语法糖,只在左侧值为 null 或 undefined 时提前返回 undefined,不再继续执行右侧访问。不是“防止 undefined 错误”,而是让访问过程对 undefined 友好——不抛错,而是静默失败。
什么时候用 ?. 能真正避免 TypeError?
典型场景是读取可能不存在的深层属性,比如 API 响应结构不稳定、表单字段动态生成、或 DOM 元素未挂载。只要中间某层是 null 或 undefined,?. 就会短路。
-
user?.profile?.avatar?.url:任一环节为null/undefined,整个表达式返回undefined,不会报Cannot read property 'avatar' of undefined -
obj?.method?.():先检查obj是否存在,再检查method是否为函数,都通过才调用 -
arr?.[0]?.name:安全读取数组首项的name字段,即使arr是undefined或空数组
?. 和逻辑运算符 && 有什么区别?
&& 是布尔逻辑,会做类型转换;?. 是属性访问控制,严格按值是否为 null/undefined 判断,且不改变原始值类型。
const obj = { value: 0 };
obj?.value; // → 0(正确拿到数字 0)
obj && obj.value; // → 0(也行,但依赖隐式转换)
const obj2 = { value: false };
obj2?.value; // → false
obj2 && obj2.value; // → false(碰巧一致)
const obj3 = { value: '' };
obj3?.value; // → ''
obj3 && obj3.value; // → ''(还是碰巧)
// 但一旦 obj 是 null:
const obj4 = null;
obj4?.value; // → undefined
obj4 && obj4.value; // → null(不是 undefined!类型不一致)
更关键的是链式访问:a?.b?.c 比 a && a.b && a.b.c 更简洁、更少重复、且支持方法调用和索引访问。
容易踩的坑:哪些地方不能用 ?.?
?. 只作用于属性访问、方法调用、数组索引三种操作。它不能解决所有“undefined 问题”:
- 不能用于赋值:❌
obj?.name = 'Alice'(语法错误) - 不能用于 delete:❌
delete obj?.name - 不能跳过
undefined后继续执行后续语句:fn()?.then(...)中如果fn()返回undefined,?.不会阻止.then被调用 —— 因为undefined.then仍会报错;此时需配合空值判断或?? - 不处理
ReferenceError:变量根本没声明,undeclaredVar?.prop依然报错,?.不起作用
真正要兜底,往往得组合使用:data?.items?.[0]?.id ?? 'default-id' —— 可选链负责安全导航,空值合并负责提供默认值。










