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 相关文章推荐
ie 处理 gif动画 的onload 事件的一个 bug
Apr 12 Javascript
JavaScript 版本自动生成文章摘要
Jul 23 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
Oct 11 Javascript
js实现多张图片延迟加载效果
Jul 17 Javascript
webpack本地开发环境无法用IP访问的解决方法
Mar 20 Javascript
Angularjs实现页面模板清除的方法
Jul 20 Javascript
JavaScript new对象的四个过程实例浅析
Jul 31 Javascript
js计算两个日期间的天数月的实例代码
Sep 20 Javascript
使用异步controller与jQuery实现卷帘式分页
Jun 18 jQuery
vue表单中遍历表单操作按钮的显示隐藏示例
Oct 30 Javascript
vue 实现通过vuex 存储值 在不同界面使用
Nov 11 Javascript
JS Web Flex弹性盒子模型代码实例
Mar 10 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 选项及相关信息函数库
2006/12/04 PHP
PHP数据库连接mysql与mysqli对比分析
2016/01/04 PHP
再谈IE中Flash控件的自动激活 ObjectWrap
2007/03/09 Javascript
js数组的基本操作(很全自己整理的)
2014/10/16 Javascript
IE6/IE7中JavaScript json提示缺少标识符、字符串或数字问题处理
2014/12/16 Javascript
AngularJS模块学习之Anchor Scroll
2016/01/19 Javascript
JS功能代码集锦
2016/05/04 Javascript
JavaScript基础知识点归纳(推荐)
2016/07/09 Javascript
js对字符串进行编码的方法总结(推荐)
2016/11/10 Javascript
JavaScript中return用法示例
2016/11/29 Javascript
原生JS封装animate运动框架的实例
2017/10/12 Javascript
nodejs acl的用户权限管理详解
2018/03/14 NodeJs
vue-cli2.x项目优化之引入本地静态库文件的方法
2018/06/19 Javascript
Vue插件从封装到发布的完整步骤记录
2019/02/28 Javascript
vue安装遇到的5个报错及解决方法
2019/06/12 Javascript
小程序跨页面交互的作用与方法详解
2020/01/07 Javascript
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
详解Python中的装饰器、闭包和functools的教程
2015/04/02 Python
进一步理解Python中的函数编程
2015/04/13 Python
python实现的简单文本类游戏实例
2015/04/28 Python
Python爬虫实例爬取网站搞笑段子
2017/11/08 Python
Flask框架Flask-Principal基本用法实例分析
2018/07/23 Python
python多进程使用及线程池的使用方法代码详解
2018/10/24 Python
python selenium执行所有测试用例并生成报告的方法
2019/02/13 Python
手把手教你使用Python创建微信机器人
2019/04/29 Python
Python for循环及基础用法详解
2019/11/08 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
TensorFlow keras卷积神经网络 添加L2正则化方式
2020/05/22 Python
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
如何设置Java的运行环境
2013/04/05 面试题
2014年大学生党课心得体会范文
2014/03/29 职场文书
中学生演讲稿
2014/04/26 职场文书
幼儿园安全责任书范本
2014/07/24 职场文书
2014年自愿离婚协议书范本
2014/09/25 职场文书
检讨书格式
2015/01/23 职场文书
特此通知格式
2015/04/27 职场文书