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 相关文章推荐
jquery 问答知识整理
Feb 11 Javascript
js简单实现让文本框内容逐个字的显示出来
Oct 22 Javascript
前端轻量级MVC框架CanJS详解
Sep 26 Javascript
JavaScript的设计模式经典之建造者模式
Feb 24 Javascript
AngularJs Modules详解及示例代码
Sep 01 Javascript
JS控件bootstrap datepicker使用方法详解
Mar 25 Javascript
微信小程序组件 marquee实例详解
Jun 23 Javascript
AngularJS实现select的ng-options功能示例
Jul 12 Javascript
element的el-table中记录滚动条位置的示例代码
Nov 06 Javascript
node.js通过url读取文件
Oct 16 Javascript
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 Vue.js
jquery插件实现悬浮的菜单
Apr 24 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
在PHP中利用wsdl创建标准webservice的实现代码
2011/12/07 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
PHP+Ajax实现的博客文章添加类别功能示例
2018/03/29 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
jQuery 数据缓存data(name, value)详解及实现
2010/01/04 Javascript
asp.net+js 实现无刷新上传解析csv文件的代码
2010/05/17 Javascript
Google 静态地图API实现代码
2010/11/19 Javascript
基于jquery的返回顶部效果(兼容IE6)
2011/01/17 Javascript
JS+CSS制作DIV层可(最小化/拖拽/排序)功能实现代码
2013/02/25 Javascript
node.js入门教程
2014/06/01 Javascript
优化RequireJS项目的相关技巧总结
2015/07/01 Javascript
js简单实现图片延迟加载的方法
2016/07/19 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
2016/10/26 Javascript
基于Node的React图片上传组件实现实例代码
2017/05/10 Javascript
Webpack执行命令参数详解
2017/06/17 Javascript
React-Native之定时器Timer的实现代码
2017/10/04 Javascript
IE9 elementUI文件上传的问题解决
2018/10/17 Javascript
基于vue.js实现分页查询功能
2018/12/29 Javascript
微信小程序 SOTER 生物认证DEMO 指纹识别功能
2019/12/13 Javascript
Python实现对文件进行单词划分并去重排序操作示例
2018/07/10 Python
python多进程实现文件下载传输功能
2018/07/28 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
Python使用sort和class实现的多级排序功能示例
2018/08/15 Python
对pandas写入读取h5文件的方法详解
2018/12/28 Python
用pycharm开发django项目示例代码
2019/06/13 Python
Python制作微信好友背景墙教程(附完整代码)
2019/07/17 Python
Django中create和save方法的不同
2019/08/13 Python
浅析使用Python搭建http服务器
2019/10/27 Python
python不同系统中打开方法
2020/06/23 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
pycharm专业版远程登录服务器的详细教程
2020/09/15 Python
html5 div布局与table布局详解
2016/11/16 HTML / CSS
大学生村官心得体会范文
2014/01/04 职场文书
高校教师自荐信范文
2014/03/13 职场文书
国庆节主题班会
2015/08/15 职场文书
Python 全局空间和局部空间
2022/04/06 Python