为变量赋默认值

读取对象属性的时候,如果某个属性的值是 null 或者 undefined ,有时候需要为它们指定默认值。以前常见的做法是通过逻辑或操作符 | | 指定默认值。

  1. const foo = qty => {
  2. qty =qty || 1000
  3. console.log(qty)
  4. }
  5. foo(); // 1000
  6. foo(1); // 1

然而,这样写是错的。开发者的原意是,只要属性的值为 null 或者 undefined ,默认值就会生效,但是由于逻辑或操作符 | | 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值( 0 , ‘’ , null , undefined )都不会被返回(转布尔值为false)。这导致如果你使用 0 , ‘’ 或 NaN 作为有效值,就会出现不可预料的后果。
image.png
为了避免这种情况,ES2020 引入了一个新的 空值合并运算符 ??(Null判断运算符)。它的行为类似 | | ,但是只有运算符左侧的值为 null 或者 undefined 时,才会返回右侧的值。

  1. let falsyText = ''; // An empty string (which is also a falsy value)
  2. let notFalsyText = falsyText || 'Hello world';
  3. console.log(notFalsyText); // hello world
  4. let preservingFalsy = falsyText ?? 'Hi world';
  5. console.log(preservingFalsy); // '' (as myText is neither undefined nor null)

跟可选链操作符(链判断运算符) ?. 配合使用,为 null 或 undefined 的值设置默认值。

  1. const user = {
  2. name: 'syukinmei',
  3. gender: 'man',
  4. };
  5. const showProvince = user.address?.province ?? '信息未录入';
  6. console.log(showProvince); // '信息未录入'

上面代码中,如果 user.address 是 null 或 undefined ,或者 user.address.province 是null 或 undefined ,就会返回默认值 ‘信息未录入’。也就是说,这一行代码包括了两级属性的判断。

注意事项

短路

?? 本质上是逻辑运算符,它与 OR(| |) 和 AND(&&) 相似符合短路逻辑,当左边表达式为 null 或 undefined 时,不会对右边表达式进行求值。

不能与 OR 或 ADN 运算符公用

同时它与 OR(| |) 和 AND(&&) 有一个优先级问题,它们之间对优先级到底孰高孰低。优先级的不同,往往会导致逻辑运算的结果不同。(它们之间的运算优先级 / 运算顺序是为定义的)如果组合使用会抛出 SyntaxError

现在的规则是,如果多个