可选链 `?.`——再也不用写一长串 `&&` 了!

引言

"Cannot read property 'name' of undefined------又是这个错!我明明已经写了 if (user && user.profile && user.profile.name) 啊!"

同事凑过来看了一眼:"你只检查了 useruser.profile,但没检查 user.profile.name 本身?哦,其实 user.profile.name 不可能是 undefined 的......等等,如果 user.profile 是空对象呢?"

我陷入了沉思:难道我要写 user && user.profile && user.profile.name && user.profile.name.firstName?这代码长得像铁轨,谁看得懂啊!

直到有一天,我发现了可选链操作符 ?.。它就像一把瑞士军刀,轻轻一划,所有 undefined 的烦恼都烟消云散。

一、传统防守:&& 的"人肉护盾"

在过去,为了安全地访问深层嵌套的属性,我们不得不写这样的代码:

javascript 复制代码
const firstName = user && user.profile && user.profile.name && user.profile.name.firstName;

如果中间任何一环是 nullundefined,整个表达式短路返回 undefined,不会报错。但这写法,读起来像在爬楼梯,每层都要确认一下。

更别提调用可能存在的方法:

javascript 复制代码
const result = api && api.getData && api.getData();

万一 api.getData 不是函数?又得加判断。

二、可选链:.?. 的优雅空降

可选链操作符 ?. 允许你读取位于连接链深处的属性,而无需显式验证每一环是否有效。如果引用是 nullundefined,表达式短路返回 undefined

javascript 复制代码
const firstName = user?.profile?.name?.firstName;

就这么简单!如果 userprofilename 任何一个不存在,整个表达式返回 undefined,而不是报错。

2.1 函数调用可选链

javascript 复制代码
const result = api?.getData?.();

如果 apinull/undefined,或者 api.getData 不是函数,都返回 undefined,不会抛错。

2.2 数组元素可选链

javascript 复制代码
const firstItem = arr?.[0];

如果 arr 不是数组或者是 null/undefined,返回 undefined

2.3 与空值合并搭配使用

javascript 复制代码
const firstName = user?.profile?.name?.firstName ?? '匿名';

如果最终结果是 undefinednull,就换成默认值。完美!

三、实战对比:代码简洁度暴增

场景1:读取深层 API 响应

javascript 复制代码
// 旧写法
const city = response && response.data && response.data.user && response.data.user.address && response.data.user.address.city;

// 新写法
const city = response?.data?.user?.address?.city;

场景2:调用可选回调

javascript 复制代码
// 旧写法
if (onSuccess && typeof onSuccess === 'function') {
  onSuccess(data);
}

// 新写法
onSuccess?.(data);

场景3:动态属性名

javascript 复制代码
const value = obj?.[key];

四、注意事项:别滥用

  • ?. 只检查左侧是否为 nullundefined ,不检查 false0'' 等假值。如果你需要过滤假值,用 ||??
  • 不能用于赋值obj?.prop = value 是语法错误。
  • 短路效应 :一旦遇到 null/undefined,右侧整个链停止求值,包括函数调用。
  • 性能 :现代浏览器对 ?. 优化很好,放心用。

五、兼容性与降级

可选链是 ES2020 特性,现代浏览器都支持(Chrome 80+、Firefox 74+、Safari 13.1+)。如果需要兼容旧浏览器,可以用 Babel 插件 @babel/plugin-proposal-optional-chaining 转译。

六、总结:告别防御性编程噩梦

可选链操作符让 JavaScript 代码变得更加简洁、安全、可读。你不再需要写一长串 && 来保护每一层属性访问,也不用担心 Cannot read property of undefined 半夜叫醒你。

记住:?. 代替 && 链,用 ?? 提供默认值。这两个好基友,能让你的代码年轻十岁。


每日一问 :你曾经因为忘记检查深层属性,导致过线上报错吗?或者写过最长的 && 链有多长?评论区晒出你的"防御塔"代码,让大家开开眼!

相关推荐
镜宇秋霖丶5 小时前
2026.5.6@霖宇博客制作中遇见的问题
前端·javascript·vue.js
吴声子夜歌6 小时前
Vue3——TypeScript基础
javascript·typescript
小李子呢02116 小时前
前端八股Vue---Vue-router路由管理器
前端·javascript·vue.js
百锦再7 小时前
Auto.js变成基础知识学习
开发语言·javascript·学习·sqlite·kotlin·android studio·数据库开发
洛_尘8 小时前
Python 5:使用库
java·前端·python
Bigger8 小时前
Bun 能上生产吗?我的实战结论
前端·node.js·bun
kyriewen10 小时前
你的前端滤镜慢得像PPT?用Rust+WebAssembly,一秒处理4K图
前端·rust·webassembly
kyriewen1110 小时前
你等的Babel编译,够喝三杯咖啡了——用Rust重写的SWC,只需眨个眼
开发语言·前端·javascript·后端·性能优化·rust·前端框架
IT_陈寒10 小时前
SpringBoot自动配置坑了我,原来要这样绕过去
前端·人工智能·后端
东方小月10 小时前
Claude Code 完整上手指南:MCP、Skills、第三方模型配置一次搞定
前端·人工智能·后端