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


Posted in Javascript onJuly 22, 2020

空值合并运算符 ?? 提供了一种简短的语法,用来获取列表中第一个“已定义”的变量(译注:即值不是 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 空值合并运算符 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript confirm选择判断
Oct 18 Javascript
使用js对select动态添加和删除OPTION示例代码
Aug 12 Javascript
jquery简单实现图片切换效果的方法
May 12 Javascript
JavaScript SHA1加密算法实现详细代码
Oct 06 Javascript
微信小程序 radio单选框组件详解及实例代码
Jan 10 Javascript
简述jQuery Easyui一些用法
Aug 01 jQuery
jQuery 中msgTips 顶部弹窗效果实现代码
Aug 14 jQuery
javascript高仿热血传奇游戏实现代码
Feb 22 Javascript
微信小程序中时间戳和日期的相互转换问题
Jul 09 Javascript
ES6 中可以提升幸福度的小功能
Aug 06 Javascript
TypeScript之调用栈的实现
Dec 31 Javascript
jQuery擦除插件eraser使用方法详解
Jan 11 jQuery
解决vue单页面 回退页面 keeplive 缓存问题
Jul 22 #Javascript
vue移动端弹起蒙层滑动禁止底部滑动操作
Jul 22 #Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
Jul 22 #Javascript
vue 弹出遮罩层样式实例
Jul 22 #Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 #Javascript
vue中实现拖动调整左右两侧div的宽度的示例代码
Jul 22 #Javascript
在vue中实现禁止回退上一步,路由不存历史记录
Jul 22 #Javascript
You might like
Mysql的常用命令
2006/10/09 PHP
无数据库的详细域名查询程序PHP版(1)
2006/10/09 PHP
利用discuz自带通行证整合dedecms的方法以及文件下载
2007/03/06 PHP
php自动加载的两种实现方法
2010/06/21 PHP
用php实现百度网盘图片直链的代码分享
2012/11/01 PHP
php+mysql实现数据库随机重排实例
2014/10/17 PHP
分享一个Laravel好用的Cache宏
2015/03/02 PHP
PHP中的print_r 与 var_dump 输出数组
2016/06/13 PHP
Yii 2.0如何使用页面缓存方法示例
2017/05/23 PHP
为JavaScript添加重载函数的辅助方法
2010/07/04 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
2011/06/27 Javascript
js保留小数点后几位的写法
2014/01/03 Javascript
js生成动态表格并为每个单元格添加单击事件的方法
2014/04/14 Javascript
javascript实现仿百度图片的瀑布流加载效果
2016/04/20 Javascript
js重写方法的简单实现
2016/07/10 Javascript
vue.js入门教程之绑定class和style样式
2016/09/02 Javascript
浅谈jquery拼接字符串效率比较高的方法
2017/02/22 Javascript
NodeJS安装图文教程
2018/04/19 NodeJs
JS数组去重常用方法实例小结【4种方法】
2018/05/28 Javascript
vue项目webpack中Npm传递参数配置不同域名接口
2018/06/15 Javascript
[01:27:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第一场 1月24日
2021/03/11 DOTA
简单讲解Python编程中namedtuple类的用法
2016/06/21 Python
win10系统下Anaconda3安装配置方法图文教程
2018/09/19 Python
Python Numpy 自然数填充数组的实现
2019/11/28 Python
python 实现单通道转3通道
2019/12/03 Python
python和node.js生成当前时间戳的示例
2020/09/29 Python
什么是封装
2013/03/26 面试题
护理自荐信范文
2013/10/05 职场文书
房屋改造计划书
2014/01/10 职场文书
2014爱耳日宣传教育活动总结
2014/03/09 职场文书
奠基仪式主持词
2014/03/20 职场文书
党支部创先争优活动总结
2014/08/28 职场文书
授权委托书(完整版)
2014/09/10 职场文书
2014年团支部工作总结
2014/11/17 职场文书
反邪教教育心得体会
2016/01/15 职场文书
Pytorch distributed 多卡并行载入模型操作
2021/06/05 Python