ES新提案:双问号操作符
摘要: 简单实用的新特性。
- 原文:ES新提案:双问号操作符
- 译者:前端小智
本文主要讲Gabriel Isenberg撰写的ES提案“Nullish coalescing for JavaScript”。 它提出?? 替换||的运算符,并提供默认值。这里先把这相提案叫作双问号操作符,如果你有好的叫法,欢迎留言讨论。
1. 概述
双问号 ?? 的操作符跟 || 类似,如果给定变量值为 null 或者 undefined,刚使用双问号后的默认值,否则使用该变量值。
如下:
> undefined ?? 'default'
'default'
> null ?? 'default'
'default'
> false ?? 'default'
false
> '' ?? 'default'
''
> 0 ?? 'default'
0
2. 早期的 || 运算符号
直接来个例子来演示一下 || 运算,下面两个等式是等价的:
a || b
a ? a : b
如果 a 是 truthy 值,则返回 a, 否则返回 b。
这使得使用||指定一个默认值成为可能,如果实际值是假的,那么将使用这个默认值:
const result = actualValue || defaultValue;
function getTitle(fileDesc) {
return fileDesc.title || '(Untitled)';
}
const files = [
{path: 'index.html', title: 'Home'},
{path: 'tmp.html'},
];
assert.deepEqual(
files.map(f => getTitle(f)),
['Home', '(Untitled)']);
请注意,基本只有在实际值undefined或为null时才应使用默认值,这是有效的,因为undefined和null都是假(虚值)的:
> undefined || 'default'
'default'
> null || 'default'
'default'
遗憾的是,如果实际值是其他的虚值,也会使用默认值:
> false || 'default'
'default'
> '' || 'default'
'default'
> 0 || 'default'
'default'
因此,这个getTitle()并不总能正常工作:
assert.equal(
getTitle({path: 'empty.html', title: ''}),
'(Untitled)');
3. 使用双问号操作符来解决 || 运算的问题
?? 主要是用来解决 || 操作符号的一些问题,以下两个表达式是等价的:
a ?? b
a !== undefined && a !== null ? a : b
默认值是这样提供的:
const result = actualValue ?? defaultValue;
对于undefined和null, ??操作符的工作原理与||操作符相同
> undefined ?? 'default'
'default'
> null ?? 'default'
'default'
除了 undefined 和 null的其它虚值,?? 不会返回默认值。
> false ?? 'default'
false
> '' ?? 'default'
''
> 0 ?? 'default'
0
使用 ?? 来重写 getTitle():
function getTitle(fileDesc) {
return fileDesc.title ?? '(Untitled)';
}
现在使用fileDesc调用它,它的.title是空字符串,仍然可以按符合咱们的预期工作:
assert.equal(
getTitle({path: 'empty.html', title: ''}),
'');
3.1 通过解构给定默认值
除了使用 ?? 给getTitle添加默认值,咱们也可以通过解构方式来给定默认值:
function getTitle({title = '(Untitled)'}) {
return title;
}
3.2 使用 ?? 操作符号的实际例子
作为一个现实的例子,咱们使用??来简化下面的函数。
function countMatches(regex, str) {
if (!regex.global) {
throw new Error('Regular expression must have flag /g: ' + regex);
}
const matchResult = str.match(regex); // null or Array
if (matchResult === null) {
return 0;
} else {
return matchResult.length;
}
}
assert.equal(
countMatches(/a/g, 'ababa'), 3);
assert.equal(
countMatches(/b/g, 'ababa'), 2);
assert.equal(
countMatches(/x/g, 'ababa'), 0);
// Flag /g is missing
assert.throws(
() => countMatches(/a/, 'ababa'), Error);
使用 ?? 操作符号后,简化如下:
function countMatches(regex, str) {
if (!regex.global) {
throw new Error('Regular expression must have flag /g: ' + regex);
}
return (str.match(regex) ?? []).length;
}
3.3 双问号(??)操作符与可选链(?)
双问号(??)的提出是为了补充可选链(?),来看看这两兄弟结合使用的场景(第A行):
const persons = [
{
surname: 'Zoe',
address: {
street: {
name: 'Sesame Street',
number: '123',
},
},
},
{
surname: 'Mariner',
},
{
surname: 'Carmen',
address: {
},
},
];
const streetNames = persons.map(
p => p.address?.street?.name ?? '(no name)'); // (A)
assert.deepEqual(
streetNames, ['Sesame Street', '(no name)', '(no name)']
);
4. 兼容性
可以通过ECMAScript Next compatibility table 查看 ?? 支持情况。
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!
ES新提案:双问号操作符的更多相关文章
- C#中双问号、双冒号等几个特殊关键字
1.@ 这个东东看似和邮件有关啊,但是在C#的世界里,可跟邮件没有一毛钱关系,它是string的女朋友(当然了string有N多女友),二者结合就可以发挥作用了.你可以给它起个名字,叫做“逐字字符串” ...
- C#中单问号,双问号的用法(转)
原文:http://hi.baidu.com/guodong828/blog/item/c78fc23f847314cb7d1e7193.html 单问号---用于给变量设初值的时候,给变量(int类 ...
- php两个问号??表示什么意思,PHP两个问号运算符,双问号表达式
有同学给子恒老师留言, 说在php源代码中看到有两个问号?? 不知道是什么意思. 其实两个问题??是php7新推出的表达式, c = a ?? b; 表示如果a非空,则c = a, 如果a为空,则 c ...
- Java 8 Lambda表达式之方法引用 ::双冒号操作符
双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名. 这里只是方法名,方法名的后面没有括号“()”.--------> 这样的式子并不代表一定会调用这个方法.这种式子一般是用作 ...
- c#的问号?和双问号??
1.问号?表示该变量可以为空 int? a=new int?(); Console.Writeline(a);//a是null 等价于: int? a=null; 也等价于下面这行,表示该变量默认为n ...
- C#单问号(?)与双问号(??)
1.单问号(?) 1.1 单问号运算符可以表示:可为Null类型,C#2.0里面实现了Nullable数据类型 //A.比如下面一句,直接定义int为null是错误的,错误提示为无法将null转化成i ...
- java :: Java中的双冒号操作符
java中的双冒号操作符 定义 双冒号运算操作符是类方法的句柄,lambda表达式的一种简写,这种简写的学名叫eta-conversion或者叫η-conversion. 通常的情况下: 把 x -& ...
- 蒲公英 · JELLY技术周刊 Vol.30: 此路不通?Vue 3 新提案 Ref-sugar
蒲公英 · JELLY技术周刊 Vol.30 随着 Vue 3 发布,相关的新闻也逐渐火热起来,而近期 RFC 中两个新的提案也因为某乎上的一些事情变得广为人关注.Ref sugar和script s ...
- C#中单问号(?)和双问号(??)的用法整理
1.单问号(?) 1.1 表示Nullable类型 C#2.0里面实现了Nullable数据类型 //A.比如下面一句,直接定义int为null是错误的,错误提示为无法将null转化成int,因为后者 ...
随机推荐
- Set a One-to-Many Relationship设置一对多关系 (EF)
In this lesson, you will learn how to set a one-to-many relationship between business objects. The C ...
- golang-基础
1.go的特点 兼具动态语言的开发效率与C,C++,java的性能安全性 ,内置编译器 2.go的安装 go的sdk下载: https://studygolang.com/dl go的IDE下载: ...
- 松软科技web课堂:JavaScript 数据类型
字符串值,数值,布尔值,数组,对象. JavaScript 数据类型 JavaScript 变量能够保存多种数据类型:数值.字符串值.数组.对象等等: var length = 7; // 数字 va ...
- Microsoft Visual Studio 2017 找不到 Visual Studio Installer
Microsoft Visual Studio 2017 找不到 Visual Studio Installer ? 打开vs2017 ,选择 工具 --> 扩展和更新 --> 联机,搜索 ...
- 假设高度已知,请写出三栏布局,其中左右各为300px 中间自适用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 父子间的通信,以及ref
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- ArcGIS api for JavaScript 3.27 在线浏览的一些小部件
var navOption; var navToolbar;// 当前选择的操作 require( [ "esri/toolbars/navigation", "esri ...
- Dynamics CRM命令栏定制基础知识及手动编辑customization.xml实例
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复166或者20151028可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 前面的博文:Dynamics C ...
- 在没有备份的情况下重新创建丢失的数据文件 (Doc ID 1149946.1)
Recreating a missing datafile with no backups (Doc ID 1149946.1) APPLIES TO: Oracle Database - Enter ...
- JVM-0-JVM知识体系