1. 首页
  2. 前端进阶
  3. ECMAScript6

ES计划新提案[双问号]操作符

本文主要讲Gabriel Isenberg撰写的ES提案“Nullish coalescing for JavaScript”。 它提出?? 替换||的运算符,并提供默认值。这里先把这相提案叫作双问号操作符,如果你有好的叫法,欢迎留言讨论。

1.概述

双问号 ?? 的操作符跟 || 类似,如果给定变量值为 null 或者 undefined,刚使用双问号后的默认值,否则使用该变量值。

如下:


//Js中文网周刊,每天一道面试题 or Js小知识 https://www.javascriptc.com/interview-tips/ > 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时才应使用默认值,这是有效的,因为undefinednull都是假(虚值)的:


> 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;

对于undefinednull??操作符的工作原理与||操作符相同


> undefined ?? 'default' 'default' > null ?? 'default' 'default'

除了 undefinednull的其它虚值,?? 不会返回默认值。


> 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)'] );

*

码农进阶题库,每天一道面试题 or Js小知识 https://www.javascriptc.com/interview-tips/

4.兼容性

可以通过ECMAScript Next compatibility table 查看 ?? 支持情况。

作者:前端小智
链接:https://segmentfault.com/a/1190000020182715

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:ES计划新提案[双问号]操作符

链接:https://www.javascriptc.com/3500.html

« 请问你都如何优化图片来提高网站的性能并送你几种小技巧
10个面试官都爱问的JavaScript面试题»
Flutter 中文教程资源

相关推荐

QR code