空值处理的工程进化是从“手动兜底”走向“语言级防护”的过程。ES5靠&&和嵌套if硬扛,易误判假值;ES2019–2020引入?.和??实现精准空值语义;现代实践将其视为基础规范,广泛用于API解构与默认值赋值。

空值处理的工程进化,本质是开发者从“手动兜底”走向“语言级防护”的过程。核心驱动力不是语法炫技,而是真实业务中反复踩坑后对安全、简洁、可读的迫切需求。
ES5 时代:靠 && 和嵌套 if 硬扛
那时没有原生空值保护机制,遇到 user.profile.address.city 这类链式访问,只能靠经验写防御代码:
- 用
&&短路:const city = user && user.profile && user.profile.address && user.profile.address.city;—— 写起来快,但逻辑隐含,且无法区分0、false、''和真正的空值; - 用嵌套
if:逐层检查user、profile、address是否存在 —— 安全但冗长,五层嵌套就让人头皮发麻; - 还常混用
||设默认值,结果把用户输入的0或空昵称''当成“空”给覆盖掉,埋下隐蔽业务 bug。
ES2019–2020:?. 和 ?? 登场,空值语义开始精准化
可选链 ?. 和空值合并 ?? 不是凭空加的糖,而是把过去靠人肉判断的逻辑,交由引擎统一识别:
-
?.只在左侧为null或undefined时中断并返回undefined,其他假值(0、false、'')照常穿透; -
??只在左侧是null或undefined时才取右侧默认值,彻底避开||对合法假值的误伤; - 两者可组合:
user?.profile?.address?.city ?? '未填写'—— 一行顶过去七八行,且语义清晰、无歧义。
现代实践:?. 和 ?? 已成默认习惯,而非“高级技巧”
在 TypeScript + ESLint + Prettier 的标准工作流里,这两者早已不是“可选优化”,而是基础编码规范:
- API 响应解构几乎必带
?.,尤其面对第三方服务字段缺失不可控的情况; - 表单字段赋默认值一律用
??,比如form.count ?? 0、user.nickname ?? ''; - 构建工具(如 Webpack、Vite)和主流框架(React/Vue/Svelte)已默认支持,无需额外 polyfill。
这条进化线没有终点,但它已经划出一条清晰分界:以前是“我得防住所有空”,现在是“我只在真为空时才干预”。语言变聪明了,人就可以更专注业务本身。

















