可选链?. 双问号??,这都是些啥

elegantYU 发布于

上海的天气,终于能穿棉衣了

记得几个月前,某篇文章中便见过对可选链?.的讲解,当时打眼一看:这是个啥(黑人问号),算了不看了,花里胡哨的。
直至某日,基友一页页代码入目,花哨且实用,这才狂拍大腿,表情狰狞却哑口无言。
”你也用过这些语法?“
”…不,我曾经见过“

可选链 ?.

optional-chaining

你是否写过这样的代码

// 若 a 存在,则判断 a.b 是否存在,再判断 a.b.c ,再...
a && a.b && a.b.c && ...

每当写此等代码,无不是心中怒骂:真 egg pain!

如今,可选链操作符可帮你走出无限判断的困境。它允许读取一个被链接对象的深层次属性的值而无需明确校验连接上的每一条引用的有效性。

例如:

const yourSelf = {
  name: "小明",
  age: 24,
  pets: {
    cat: {
      name: "狗剩"
    },
    dog: null
  }
};

const dogName = yourSelf.pets?.dog?.name;
const catName = yourSelf.pets.cat?.name;
const girlfriend = yourSelf?.girlfriend;

console.log(dogName, catName, girlfriend);

// print > undefined '狗剩' undefined

你甚至能用在更多的地方

function wantCallback(data, callback) {
  try {
    ...
  }
  catch (err) {
    if (callback) {
      callback(err.message)
    }
    // 或者这样?
    callback && callback(err.message)
    // 不用这么麻烦,只需一步
    callback?.(err.message)
  }
}

双问号 ??

nullish-coalescing-operator 合并操作符?不知道怎么翻译

沿用上面的例子,如果输出你的女友数量,女友属性不存在或为 null 时输出’单身狗不配有女友这个属性’,该如何做呢

const yourSelf = {
  ...
  girlfriend: 0
}

console.log(yourSelf?.girlfriend || '单身狗不配有女友这个属性')
//  这样是预期结果吗,并不是,是希望你输出 0

console.log(yourSelf?.girlfriend === 0 ? 0 : yourSelf?.girlfriend || '单身狗不配有女友这个属性')
//  虽然结果出来了,但是代码易读性却降低了很多,很不优雅

传统的或运算符||会在运算结果为0 false '' null undefined时都使用设置的默认结果,而0 false ''都是需要实际输出的值。
这里,就可以使用双问号??运算符替代||,它会返回实际的结果.

const girlfriendNumber = yourSelf?.girlfriend ?? "单身狗不配有女友这个属性";

console.log(girlfriendNumber); //  输出 > 0

是否很优雅、简洁、实用?那么请问哪里能买到怎么使用呢?
很简单,这两种特性都处于 stage3 的阶段,配置对应的 babel 插件即可尝鲜。

module.exports = {
  plugins: [
    "@babel/plugin-proposal-optional-chaining",
    "@babel/plugin-proposal-nullish-coalescing-operator"
  ]
};

新版本的 typescript 已全支持两种运算符(羡慕).

- Stage 0 - Strawman: just an idea, possible Babel plugin.
- Stage 1 - Proposal: this is worth working on.
- Stage 2 - Draft: initial spec.
- Stage 3 - Candidate: complete spec and initial browser implementations.
- Stage 4 - Finished: will be added to the next yearly release.