可选链与空值合并:告别 && 地狱
可选链与空值合并:告别 && 地狱
ES2020 里我最喜欢的两个语法:可选链 ?. 和空值合并 ??。它们不引入新概念,只是把两个最常见的防御性写法变成了一等公民。
?.:深层取值不再叠 &&
以前从接口数据里取深层字段:
const city = data && data.user && data.user.address && data.user.address.city
现在:
const city = data?.user?.address?.city
中间任何一环是 null 或 undefined,整个表达式短路返回 undefined,不再层层判断。
还支持两种变体:
// 数组/动态键
const first = list?.[0]
const val = obj?.[key]
// 方法调用(方法不存在时不调用,返回 undefined)
obj.onChange?.(value)
obj.method?.() 这个写法在调可选回调时特别好用,以前要写 if (obj.onChange) obj.onChange(v)。
注意:短路不是万能的
// 前面用了 ?. 后面又裸取属性,照样可能炸
const len = data?.user.name // data 是 null 时 -> TypeError
// 正确:链条不能断
const len2 = data?.user?.name
还有一个容易忽略的:?. 只对 null 和 undefined 短路。如果中间值是 0、'' 这种 falsy 但不是空值的,会继续往下走然后报 TypeError——这其实是正确行为,真遇到了说明数据结构本身有问题。
??:只把 null/undefined 当"空"
以前给默认值:
const count = input.count || 10
问题来了:count 是 0 的时候,|| 也会判定为"空",返回 10——但 0 明明是个合法值!空字符串、false 同理。
?? 只在左边是 null 或 undefined 时才用右边的默认值:
const count = input.count ?? 10 // count = 0 时,结果正确为 0
const text = input.text ?? '默认' // text = '' 时保留 ''
黄金搭档
const pageSize = config?.pagination?.pageSize ?? 20
这一行覆盖了过去四五行的防御代码,而且语义更精确。
改写老代码的原则
a && a.b && a.b.c这种纯防御空值的链,放心改a?.b?.cx || default别盲目改??:先想清楚 falsy 值(0、''、false)是不是合法输入。配置项、表单数字通常该改;而"空字符串也视为未填"的场景保留||反而对?.()调回调很香,但别在需要明确报错的地方用它掩盖 bug
兼容性
2020 年的新语法,现代浏览器和 Node 14+ 都支持,Babel/TS 也能转译。唯一的成本是团队约定:改就统一改,别一半 ?. 一半 && 混着写。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~