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 相关文章推荐
ajax 文件上传应用简单实现
Mar 03 Javascript
IE bug table元素的innerHTML
Jan 11 Javascript
对象题目的一个坑 理解Javascript对象
Dec 22 Javascript
第六章之辅组类与响应式工具
Apr 25 Javascript
Javascript使用SWFUpload进行多文件上传
Nov 16 Javascript
微信小程序 textarea 详解及简单使用方法
Dec 05 Javascript
Node.js 使用命令行工具检查更新
Jun 08 Javascript
浅析Visual Studio Code断点调试Vue
Feb 27 Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
Mar 01 Javascript
VUE组件中的 Drawer 抽屉实现代码
Aug 06 Javascript
微信小程序监听用户登录事件的实现方法
Nov 11 Javascript
详细谈谈JavaScript中循环之间的差异
Aug 23 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
WAR3重制版DOTA 5V5初体验
2020/04/09 DOTA
PHP实现的sqlite数据库连接类
2014/12/12 PHP
PHP session会话操作技巧小结
2016/09/27 PHP
PHP微信红包生成代码分享
2016/10/06 PHP
javascript 获取元素样式必杀技
2014/05/04 Javascript
node.js WEB开发中图片验证码的实现方法
2014/06/03 Javascript
javascript的正则匹配方法学习
2016/02/24 Javascript
对js中回调函数的一些看法
2016/08/29 Javascript
JS Select下拉框(支持输入模糊查询)
2017/02/04 Javascript
jquery ui sortable拖拽后保存位置
2017/04/27 jQuery
基于 Vue 的树形选择组件的示例代码
2017/08/18 Javascript
Angular实现的table表格排序功能完整示例
2017/12/22 Javascript
小程序数据通信方法大全(推荐)
2019/04/15 Javascript
JS页面获取 session 值,作用域和闭包学习笔记
2019/10/16 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
koa2 数据api中间件设计模型的实现方法
2020/07/13 Javascript
JavaScript缓动动画函数的封装方法
2020/11/25 Javascript
[00:55]深扒TI7聊天轮盘语音出处3
2017/05/11 DOTA
paramiko模块安装和使用(远程登录服务器)
2014/01/27 Python
详解Python使用simplejson模块解析JSON的方法
2016/03/24 Python
python读取图片并修改格式与大小的方法
2018/07/24 Python
Python日志模块logging基本用法分析
2018/08/23 Python
python re库的正则表达式入门学习教程
2019/03/08 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
2019/07/23 Python
python3实现弹弹球小游戏
2019/11/25 Python
Python利用Xpath选择器爬取京东网商品信息
2020/06/01 Python
matplotlib部件之套索Lasso的使用
2021/02/24 Python
Html5新特性用canvas标签画多条直线附效果截图
2014/06/30 HTML / CSS
《三峡》教学反思
2014/03/01 职场文书
政府门卫岗位职责
2014/04/29 职场文书
校运动会广播稿300字
2014/10/07 职场文书
2014年作风建设剖析材料
2014/10/23 职场文书
2016大学先进团支部事迹材料
2016/03/01 职场文书
幼儿园教学反思范文
2016/03/02 职场文书
Python实现为PDF去除水印的示例代码
2022/04/03 Python
Python安装使用Scrapy框架
2022/04/12 Python