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,因为后者 ...
随机推荐
- Spring MVC的注解二
概述 Spring从2.5版本开始引入注解,虽然版本不断变化,但是注解的特性一直被延续下来并不断进行扩展,这里就来记录一下Spring MVC中常用的注解,本文承接前文继续记录@PathVariabl ...
- 松软科技带你学前端:JavaScript 输出
JavaScript 不提供任何内建的打印或显示函数. JavaScript 显示方案 JavaScript 能够以不同方式“显示”数据: 使用 window.alert() 写入警告框 使用 doc ...
- 7.智能快递柜(APP及微信公众号)
1.智能快递柜(开篇) 2.智能快递柜(终端篇) 3.智能快递柜(通信篇-HTTP) 4.智能快递柜(通信篇-SOCKET) 5.智能快递柜(通信篇-Server程序) 6.智能快递柜(平台篇) 7. ...
- Thymeleaf常用语法:HTML属性设置
使用Thymeleaf的属性来设置HTML属性.(1)使用th:attr属性可以修改原来HTML节点的属性:(2)th:attr属性可以同时设置多个属性:(3)每一个HTML属性都有对应的Thymel ...
- [转]Java虚拟机类加载机制
原文地址:http://blog.csdn.net/u013256816/article/details/50829596 看到这个题目,很多人会觉得我写我的java代码,至于类,JVM爱怎么加载就怎 ...
- java8一些语法使用例子
package com.ladeng.jdk8; import com.google.common.collect.Lists;import java.util.*;import java.util. ...
- 第6次作业--static关键字、对象
题目1:编写一个类Computer,类中含有一个求n的阶乘的方法.将该类打包,并在另一包中的Java文件App.java中引入包,在主类中定义Computer类的对象,调用求n的阶乘的方法(n值由参数 ...
- 【转】MyBatis缓存机制
转载:https://blog.csdn.net/bjweimengshu/article/details/79988252. 本文转载自公众号 美团技术点评 前言 MyBatis是常见的Java数据 ...
- CF1253E Antenna Coverage(DP)
本题难点在正确性证明. 令 \(f_i\) 表示 \([1,i]\) 被全部覆盖的最小花费.答案为 \(f_m\). 首先发现,添加一个区间 \([0,0]\) 不会影响答案.所以 \(f_i\) 的 ...
- Tensorflow.nn 核心模块详解
看过前面的例子,会发现实现深度神经网络需要使用 tensorflow.nn 这个核心模块.我们通过源码来一探究竟. # Copyright 2015 Google Inc. All Rights Re ...