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

引言

"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 半夜叫醒你。

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


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

相关推荐
Mintopia1 小时前
前端卡顿的真相:不是你代码慢,是你阻塞了
前端
Mintopia1 小时前
别再乱加缓存:一套判断"该不该缓存"的方法
前端
AnalogElectronic1 小时前
html+js+css实现七龙珠神龙召唤特效
javascript·css·html
Leisureconfused1 小时前
【记录】Node版本兼容性问题及解决
前端·vue.js·npm·node.js
Highcharts.js1 小时前
React 应用中的图表选择:Highcharts vs Apache ECharts 深度对比
前端·javascript·react.js·echarts·highcharts·可视化图表·企业级图表
腹黑天蝎座1 小时前
如何实现自定义的虚拟列表
前端·react.js
用户350144817922 小时前
继承和原型链:js如何实现继承
前端
Bernard02152 小时前
给普通人的 AI 黑话翻译手册:一文看懂 LLM、RAG、Agent 到底是什么
前端·后端