ES2020系列之空值合并运算符 '??'

空值合并运算符 ?? 提供了一种简短的语法,用来获取列表中第一个“已定义”的变量(译注:即值不是 null 或 undefined 的变量)。

a ?? b 的结果是:

  • a,如果 a 不是 null 或 undefined,
  • b,其他情况。

所以,x = a ?? b 是下面这个表达式的简写:

x = (a !== null && a !== undefined) ? a : b;

下面是一个更长一点的例子。

假设,我们有一个用户,变量 firstName、lastName 和 nickName 分别对应用户的名字、姓氏和昵称。如果用户决定不输入任何值,那么这些变量都可能是未定义的。

我们想要显示用户的名称:显示这三个变量中的一个,如果都没有设置值,则显示 "Anonymous"。
让我们使用 ?? 运算符选择第一个已定义的变量:

let firstName = null;
let lastName = null;
let nickName = "Supercoder";

// 显示第一个不是 null/undefined 的值
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder

与 || 比较

或运算符 || 可以与 ?? 运算符以同样的方式使用。正如 上一章 所讲的,我们可以用 || 替换上面示例中的 ??,也可以获得相同的结果。

重要的区别是:

  • || 返回第一个 真 值。
  • ?? 返回第一个 已定义的 值。

当我们想将 null/undefined 与 0 区别对待时,这个区别至关重要。

例如,考虑下面这种情况:

height = height ?? 100;

如果 height 未定义,则将其赋值为 100。

让我们将其与 || 进行比较:

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0

在这个例子中,height || 100 将值为 0 的 height 视为未设置的(unset),与 null、undefined 以及任何其他假(falsy)值同等对待。因此得到的结果是 100。

height ?? 100 仅当 height 确实是 null 或 undefined 时才返回 100。因此,alert 按原样显示了 height 值 0。

哪种行为更好取决于特定的使用场景。当高度 0 为有效值时,?? 运算符更适合。

优先级

?? 运算符的优先级相当低:在 MDN table中为 5。

因此,?? 在大多数其他运算之后,但在 = 和 ? 之前进行运算。

如果我们需要在复杂表达式中使用 ?? 进行取值,需要考虑加括号:

let height = null;
let width = null;

// 重要:使用括号
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

否则,如果我们省略了括号,* 的优先级比 ?? 高,会优先执行。

运算过程将等同于下面这个表达式:

// 可能不正确的
let area = height ?? (100 * width) ?? 50;

这里还有一个相关的语言级别的限制。

出于安全原因,禁止将 ?? 运算符与 && 和 || 运算符一起使用。

下面的代码会触发一个语法错误:

let x = 1 && 2 ?? 3; // Syntax error

这个限制无疑是值得商榷的,但是它被添加到语言规范中是为了避免编程错误,因为人们开始使用 ?? 替代 ||。

可以明确地使用括号来解决这个问题:

let x = (1 && 2) ?? 3; // 起作用

alert(x); // 2

总结

空值合并运算符 ?? 提供了一种简洁的方式获取列表中“已定义”的值。

它被用于为变量分配默认值:

// 当 height 的值为 null 或 undefined 时,将 height 的值设置为 100
height = height ?? 100;

?? 运算符的优先级非常低,只略高于 ? 和 =。

如果没有明确添加括号,不能将其与 || 或 && 一起使用。

到此这篇关于ES2020系列之空值合并运算符 '??'的文章就介绍到这了,更多相关ES2020 空值合并运算符 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 十分钟教你上手ES2020新特性

    前言 ES2020 是 ECMAScript 对应 2020 年的版本.这个版本不像 ES6 (ES2015)那样包含大量新特性.但也添加了许多有趣且有用的特性.想阅读更多优质文章,请点击我的博客 本文以简单的代码示例来介绍 ES2020新特性.这样,你可以很快理解这些新功能,而不需要多么复杂的解释. 可选链操作符(Optional Chaining) 可选链 可让我们在查询具有多个层级的对象时,不再需要进行冗余的各种前置校验. 日常开发中,当需要访问嵌套在对象内部好几层的属性时,可能就会得到臭

  • ES2020 新特性(种草)

    这几年,Ecma TC39一年一次更新 ecmascript 规范标准,截止目前,以下特性已进入 finished 状态.现在带大家体验种草 ES2020 新特性. 一:Promise.allSettled Promise.all 缺陷 都知道 Promise.all 具有并发执行异步任务的能力.但它的最大问题就是如果其中某个任务出现异常(reject),所有任务都会挂掉,Promise直接进入 reject  状态. 想象这个场景:你的页面有三个区域,分别对应三个独立的接口数据,使用 Prom

  • ES2020 已定稿,真实场景案例分析

    近年来,JavaScript 的发展非常迅速. 尤其是在2015 年 ES6 发布之后,情况变得更好. 现在 许多新的特性被提议包括在 ES2020版本中.好消息是这些已经已经敲定. 现在,我们获得了最终定稿的功能清单,它们将在被批准发布之后出现在备受期待的 ES2020 中. 其中一些功能使我非常兴奋,因为在它们存在之前编写代码时遇到将会遇到很多麻烦. 让我们看看它们是什么吧! 可选链操作符(Optional Chaining Operator) 对我个人来说,这是 ES2020最令人兴奋的特

  • ES2020系列之空值合并运算符 '??'

    空值合并运算符 ?? 提供了一种简短的语法,用来获取列表中第一个"已定义"的变量(译注:即值不是 null 或 undefined 的变量). a ?? b 的结果是: a,如果 a 不是 null 或 undefined, b,其他情况. 所以,x = a ?? b 是下面这个表达式的简写: x = (a !== null && a !== undefined) ? a : b; 下面是一个更长一点的例子. 假设,我们有一个用户,变量 firstName.lastNa

  • 详解PHP中的null合并运算符

    null合并运算符是一个好东西,有了它我们就能很方便的获取一个参数,并能在其为空的情况下提供一个默认值.比如在js中可以用||来搞: function setSomething(a){ a = a || 'some-default-value'; // ... } 而在PHP中,可惜PHP的||总是返回true或false,无法这样来搞.  PHP7才正式加入了??这个运算符: // 获取user参数的值(如果为空,则用'nobody') $username = $_GET['user'] ??

  • c# 空合并运算符“??”的使用详解

    在c#中"??"为空合并运算符,用于定义可空类型和引用类型的默认值. (1)如果此运算符的左操作数不为 null,则此运算符将返回左操作数:否则返回右操作数.例:a??b,当a为null时则返回b,a不为空时返回a本身. (2)右操作数类型必须与左操作数类型相同,或者可以隐式的转换为左操作数类型.否则编译错误. (3)空合并运算符为右结合运算符,即操作时从右向左进行组合的.例:"a??b??c"的形式按"a??(b??c)"计算.

  • numpy系列之数组合并(横向和纵向)

    目录 1.横向合并 1.1 concatenate方法 1.2 hstack方法 1.3 column_stack方法 2.纵向合并 2.1 concatenate方法 2.2 vstack方法 2.3 row_stack方法 先新建两个数组用于合并 import numpy as np arr1 = np.array([[1, 2, 3], [4, 5, 6]]) print(arr1) result: [[1 2 3]  [4 5 6]] arr2 = np.array([[7, 8, 9]

  • C# null 合并运算符??(双问号)使用示例

    ??是一个二元运算符,如果左操作数非空,则返回左操作数,否则返回右操作数,所以,在一些特定的场合可以用它来代替?:运算符,简化代码书写. 例1: 复制代码 代码如下: int length = Request.QueryString["l"] != null ? int.Parse(Request.QueryString["l"]) : 0; 使用??运算符: 复制代码 代码如下: int length = int.Parse(Request.QueryString

  • Swift心得笔记之运算符

    空值合并运算符和区间运算符 今天主要看的内容是 Swift 中的基本运算符.记录一下. Nil Coalescing Operator a ?? b 中的 ?? 就是是空值合并运算符,会对 a 进行判断,如果不为 nil 则解包,否则就返回 b . var a: String? = "a" var b: String? = "b" var c = a ?? b // "a" a = nil c = a ?? b // "b"

  • js中不常见的运算符与操作符总结

    javaScript常用运算符和操作符总结 类别 操作符 算术操作符 +. –. *. /. %(取模) 字符串操作符 + 字符串连接   +=字符串连接复合 布尔操作符 !. &&.  ||  一元操作符 ++ . -- .  +(一元加).    -(一元减) 关系比较操作符 < . <= . >  .>=.   !=  . == .  === .  !==  按位操作符 ~ 按位非    &按位与     | 按位或     ^按位异或    <

  • 一起盘点JavaScript中一些强大的运算符

    目录 前言 一.??空值合并运算符 二.??=空赋值运算符 三.?.可选链操作符 四.?:三元运算符 五.逻辑与(&&)和逻辑或(||) 六.位运算符 & 和 | 七.双位运算符 ~~ 七.逻辑运算符 ! 7.1 利用!取反 7.2 利用!!做类型判断 7.3 两个值是否相等 总结 前言 你在阅读其他人的代码的时候,有没有遇见一些奇怪的写法,让你的思路瞬间卡住,等你回过神来便不明觉厉,某位大侠曾经来过这里. 今天,我们就来盘点一下 JavaScript 中一些强大的运算符吧~~~

  • 帮你提高开发效率的JavaScript20个技巧

    目录 1. 申明和初始化数组 2.进行求和.最小值和最大值 3. 对字符串.数字或对象的数组进行排序 4. 是否需要从一个数组中过滤掉无用的值? 5. 为各种条件使用逻辑运算符 6. 删除重复的值 7. 创建一个计数器对象或Map 8. 三元运算符很酷 9. 与传统的once相比,for循环更快. 10. 合并两个对象 11. 箭头函数 12. 可选链式 13. 打乱一个数组 14. 空值合并运算符 15. Rest & Spread 运算符 16. 缺省参数 17. 将十进制转换为二进制或十六

随机推荐