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 相关文章推荐
js中将多个语句写成一个语句的两种方法小结
Dec 08 Javascript
jquery实现pager控件示例
Apr 09 Javascript
js判断浏览器类型为ie6时不执行
Jun 15 Javascript
JavaScript避免内存泄露及内存管理技巧
Sep 05 Javascript
JavaScript学习笔记之Function对象
Jan 22 Javascript
jQuery 遍历函数详解
Jul 05 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
Mar 01 Javascript
jQuery选择器之子元素选择器详解
Sep 18 jQuery
echarts设置图例颜色和地图底色的方法实例
Aug 01 Javascript
小程序中canvas的drawImage方法参数使用详解
Jul 04 Javascript
js实现时分秒倒计时
Dec 03 Javascript
详解vue3.0 diff算法的使用(超详细)
Jul 01 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脚本不报错的原因
2014/06/12 PHP
HTML中嵌入PHP的简单方法
2016/02/16 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
jquery text(),val(),html()方法区别总结
2013/11/04 Javascript
jquery下div 的resize事件示例代码
2014/03/09 Javascript
轻松创建nodejs服务器(5):事件处理程序
2014/12/18 NodeJs
JQuery 两种方法解决刚创建的元素遍历不到的问题
2016/04/13 Javascript
快速获取/设置iframe内对象元素的几种js实现方法
2016/05/20 Javascript
jquery插件方式实现table查询功能的简单实例
2016/06/06 Javascript
基于JavaScript实现熔岩灯效果导航菜单
2017/01/04 Javascript
Ionic + Angular.js实现验证码倒计时功能的方法
2017/06/12 Javascript
解决Extjs下拉框不显示的问题
2017/06/21 Javascript
jQuery实现的简单拖拽功能示例【测试可用】
2018/08/14 jQuery
layui中table表头样式修改方法
2018/08/15 Javascript
js简单遍历获取对象中的属性值的方法示例
2019/06/19 Javascript
微信小程序实现商城倒计时
2020/11/01 Javascript
[55:32]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第二场
2018/04/05 DOTA
在Python中定义和使用抽象类的方法
2016/06/30 Python
详解python的数字类型变量与其方法
2016/11/20 Python
对python 矩阵转置transpose的实例讲解
2018/04/17 Python
python MNIST手写识别数据调用API的方法
2018/08/08 Python
Python实现iOS自动化打包详解步骤
2018/10/03 Python
基于Python批量生成指定尺寸缩略图代码实例
2019/11/20 Python
numpy矩阵数值太多不能全部显示的解决
2020/05/14 Python
通过python-pptx模块操作ppt文件的方法
2020/12/26 Python
Peter Alexander新西兰站:澳大利亚领先的睡衣设计师品牌
2016/12/10 全球购物
爱尔兰领先的在线体育用品零售商:theGAAstore
2018/04/16 全球购物
Superdry极度干燥美国官网:英国制造的服装品牌
2018/11/13 全球购物
北美最大的零售退货翻新商:VIP Outlet
2019/11/21 全球购物
银行会计职员个人的自我评价
2013/09/29 职场文书
农民工讨薪标语
2014/06/26 职场文书
代理人委托书
2014/08/01 职场文书
2014年物流工作总结
2014/11/25 职场文书
争做文明公民倡议书
2019/06/24 职场文书
创业计划书之校园跑腿公司
2019/09/24 职场文书
Python爬虫基础初探selenium
2021/05/31 Python