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 学习笔记(六)
Dec 31 Javascript
基于OO的动画附加插件,可以实现弹跳、渐隐等动画效果 分享
Jun 24 Javascript
jQuery对html元素的取值与赋值实例详解
Dec 18 Javascript
探究Javascript模板引擎mustache.js使用方法
Jan 26 Javascript
浅析JS操作DOM的一些常用方法
May 13 Javascript
微信小程序 progress组件详解及实例代码
Oct 25 Javascript
JavaScript中附件预览功能实现详解(推荐)
Aug 15 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
Oct 26 Javascript
使用Vue.js开发微信小程序开源框架mpvue解析
Mar 20 Javascript
使用webpack4编译并压缩ES6代码的方法示例
Apr 24 Javascript
使vue实现jQuery调用的两种方法
May 12 jQuery
Javascript如何实现双指控制图片功能
Feb 25 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
如何使用脚本模仿登陆过程
2006/11/22 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
JSON字符串传到后台PHP处理问题的解决方法
2016/06/05 PHP
PHP基于Closure类创建匿名函数的方法详解
2017/08/17 PHP
详谈PHP中public,private,protected,abstract等关键字的用法
2017/12/31 PHP
PhpStorm 2020.3:新增开箱即用的PHP 8属性(推荐)
2020/10/30 PHP
JS修改iframe页面背景颜色的方法
2015/04/01 Javascript
原生js配合cookie制作保存路径的拖拽
2015/12/29 Javascript
前端设计师们最常用的JS代码汇总
2016/09/25 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
2016/10/26 Javascript
详解vue与后端数据交互(ajax):vue-resource
2017/03/16 Javascript
详解用webpack2.0构建vue2.0超详细精简版
2017/04/05 Javascript
使用 js 简单的实现 bind、call 、aplly代码实例
2019/09/07 Javascript
改变layer confirm弹窗按钮的颜色方法
2019/09/12 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
使用Vue实现简单计算器
2020/02/25 Javascript
js实现页面图片消除效果
2020/03/24 Javascript
使用rpclib进行Python网络编程时的注释问题
2015/05/06 Python
基于django channel实现websocket的聊天室的方法示例
2019/04/11 Python
python实现名片管理系统项目
2019/04/26 Python
Python模块汇总(常用第三方库)
2019/10/07 Python
Python从列表推导到zip()函数的5种技巧总结
2019/10/23 Python
Python基础之字典常见操作经典实例详解
2020/02/26 Python
html5 css3 动态气泡按钮实例演示
2012/12/02 HTML / CSS
C语言基础笔试题
2013/04/27 面试题
医科大学毕业生自荐信
2014/02/03 职场文书
采购部部长岗位职责
2014/02/06 职场文书
集中采购方案
2014/06/10 职场文书
反邪教标语
2014/06/23 职场文书
安全标兵事迹材料
2014/08/17 职场文书
乡镇干部个人对照检查材料(群众路线)
2014/09/26 职场文书
授权委托书协议书
2014/10/16 职场文书
护士个人总结范文
2015/02/13 职场文书
2015年教学副校长工作总结
2015/07/22 职场文书
毕业晚宴祝酒词
2015/08/11 职场文书
2016年感恩父亲节活动总结
2016/04/01 职场文书