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动态调整iframe高度的代码
Apr 10 Javascript
javascript 拖动表格行实现代码
May 05 Javascript
JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题
Sep 28 Javascript
让新消息在网页标题闪烁提示的jQuery代码
Nov 04 Javascript
jquery实现漂亮的二级下拉菜单代码
Aug 26 Javascript
JavaScript实现DOM对象选择器
Sep 24 Javascript
jQuery插件FusionCharts绘制2D环饼图效果示例【附demo源码】
Apr 10 jQuery
完美解决axios在ie下的兼容性问题
Mar 05 Javascript
layui 设置table 行的高度方法
Aug 17 Javascript
JS实现百度网盘任意文件强制下载功能
Aug 31 Javascript
在vue中解决提示警告 for循环报错的方法
Sep 28 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
Apr 30 Javascript
解决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操作文件类的函数代码(文件和文件夹创建,复制,移动和删除)
2011/11/10 PHP
thinkphp实现图片上传功能
2016/01/13 PHP
thinkPHP5.0框架安装教程
2017/03/25 PHP
php写一个函数,实现扫描并打印出自定目录下(含子目录)所有jpg文件名
2017/05/26 PHP
JavaScript中number转换成string介绍
2014/12/31 Javascript
JS实现网站菜单拖拽移位效果的方法
2015/09/24 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
2017/07/11 Javascript
vue2.0路由切换后页面滚动位置不变BUG的解决方法
2018/03/14 Javascript
JavaScript中七种流行的开源机器学习框架
2018/10/11 Javascript
seajs和requirejs模块化简单案例分析
2019/08/26 Javascript
javascript实现视频弹幕效果(两个版本)
2019/11/28 Javascript
ES6如何用一句代码实现函数的柯里化
2020/01/18 Javascript
详解vue父子组件状态同步的最佳方式
2020/09/10 Javascript
Python开发编码规范
2006/09/08 Python
Windows下实现Python2和Python3两个版共存的方法
2015/06/12 Python
Windows下安装python MySQLdb遇到的问题及解决方法
2017/03/16 Python
Python计时相关操作详解【time,datetime】
2017/05/26 Python
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
2019/11/08 Python
python删除某个目录文件夹的方法
2020/05/26 Python
Pycharm github配置实现过程图解
2020/10/13 Python
分享30个新鲜的CSS3打造的精美绚丽效果(附演示下载)
2012/12/28 HTML / CSS
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
网易微博Web App用HTML5开发的过程介绍
2012/06/13 HTML / CSS
苹果Mac升级:MacSales.com
2017/11/20 全球购物
什么是事务?为什么需要事务?
2012/01/09 面试题
我的小天地教学反思
2014/04/30 职场文书
乡镇干部个人对照检查材料(群众路线)
2014/09/26 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
毕业纪念册寄语大全
2015/02/26 职场文书
大学生就业推荐表自我评价
2015/03/02 职场文书
2015年助残日活动总结
2015/03/27 职场文书
2016党校学习心得体会范文
2016/01/07 职场文书
python计算列表元素与乘积详情
2022/08/05 Python