【每天学一点】-Typescript: 可选访问操作符 '?.' 空合并操作符 '??'

736 阅读3分钟

Typescript release-notes

PS 看官方举例、恍然大悟

可选访问操作符 ?. 空合并操作符 ??

可选链和可选属性访问操作符 ?.

可选属性访问

可选链的核心 是让我们在写 Typescript 代码时,当我们的代码运行进入 null 或者 undefined时,可以立即停止运行某些表达式。可选链最重要的是可选访问操作符?.。代码如下:

let x = foo?.bar.baz();

这就是说,当foo被定义时,foo.bar.baz()将被计算;但当foo为null或undefined时,停止我们正在做的,返回undefined "

更简单地说,该代码片段与下面的代码相同:

let x = foo === null || foo === undefined ? undefined : foo.bar.baz();

注意,如果bar为null或undefined,我们的代码在访问baz时仍然会触发错误。同样,如果baz为null或undefined,我们将在调用?.地方触发错误。可选访问操作符 ?.只检查它左边的值是null还是unfined——而不检查任何后续属性。

// Before
if (foo && foo.bar && foo.bar.baz) {
  // ...
}

// After-ish
if (foo?.bar?.baz) {
  // ...
}

记住?.与那些&&操作符不同,因为&&将特别作用于“假”值(例如空字符串、0、NaN,以及false),但这是该构造有意为之的特性。它不会短路有效的数据,如0或空字符串。

可选元素访问

可选链还包括两个其他操作。首先是可选元素访问,它类似于可选属性访问,但允许我们访问非标识符属性(例如任意字符串、数字和符号):

/**
 * Get the first element of the array if we have an array.
 * Otherwise return undefined.
 */
function tryGetFirstElement<T>(arr?: T[]) {
  return arr?.[0];
  // equivalent to
  //   return (arr === null || arr === undefined) ?
  //       undefined :
  //       arr[0];
}

可选调用

还有一个可选调用,它允许我们在表达式不为null或undefined的情况下有条件地调用表达式。

async function makeRequest(url: string, log?: (msg: string) => void) {
  log?.(`Request started at ${new Date().toISOString()}`);
  // roughly equivalent to
  //   if (log != null && log!=undefined) {
  //       log(`Request started at ${new Date().toISOString()}`);
  //   }

  const result = (await fetch(url)).json();

  log?.(`Request finished at at ${new Date().toISOString()}`);

  return result;
}

可选链短路行为

可选链具有的“短路”行为是有限的属性访问元素访问可选调用、——它不会从这些表达式进一步展开。换句话说:

let result = foo?.bar / someComputation();

不会阻止除法someComputation() 调用的发生。它等于

let temp = foo === null || foo === undefined ? undefined : foo.bar;

let result = temp / someComputation();

这可能会导致除数undefined,这就是为什么在strictNullChecks中,以下是一个错误。

function barPercentage(foo?: { bar: number }) {
  return foo?.bar / 100;
  //     ~~~~~~~~
  // Error: Object is possibly undefined.
}

空合并(Nullish Coalescing )操作符

nullish合并操作符是另一个即将推出的ECMAScript特性,它与可选链密切相关;

你可以想到这个功能——??操作符——在处理null或undefined时,作为一种回退默认值的方法。当我们写代码的时候

let x = foo ?? bar();

这是一种新的方式,说明foo值在“存在”时将被使用;但当它为nullundefined时,计算bar()代替它。 同样,上面的代码等价于下面的代码。

let x = foo !== null && foo !== undefined ? foo : bar();

??操作符使用场景

??操作符 当尝试使用默认值时,操作符可以替换||的用法。例如,下面的代码片段试图获取上次保存在localStorage中的volume(如果它曾经保存过);然而,它有一个错误,因为它使用||。


function initializeAudio() {
  let volume = localStorage.volume || 0.5;

  // ...
}

当localStorage。如果volume设置为0,页面会将volume设置为0.5,这不是我们想要的。

总结

??操作符避免0NaN""被当作假值处理的一些意外行为。