const re = /\b(?<dup>\w+)\s+\k<dup>\b/;
const match = re.exec('Get that that cat off the table!');
console.log(match.index); // → 4
console.log(match[0]); // → that that
要将命名捕获组插入replace()方法的替换字符串,您需要使用$ <name>语法。例如:
const str = 'red & blue';
console.log(str.replace(/(red) & (blue)/, '$2 & $1'));
// → blue & red
console.log(str.replace(/(?<red>red) & (?<blue>blue)/, '$<blue> & $<red>'));
// → blue & red
const re = /(?<!un)available/;
console.log(re.exec('We regret this service is currently unavailable'));
// → null
console.log(re.exec('The service is available'));
// → ["available", index: 15, input: "The service is available", groups: undefined]
function fn(string, substitute) {
if(substitute === 'ES6') {
substitute = 'ES2015'
}
return substitute + string[1];
}
const version = 'ES6';
// 调用函数并传递模板文字。
const result = fn`${version} was a major update`;
console.log(result); // → ES2015 was a major update
第九版ECMAScript标准,正式名称为ECMAScript 2018(简称ES2018),于2018年6月发布。从ES2016开始,ECMAScript规范的新版本每年发布一次,而不是每几年发布一次,并且添加的功能少于主要版本。ES2018添加了四个新的功能:新的
RegExp
功能 ,rest/spread
属性,asynchronous iteration
和Promise.prototype.finally
。此外,ES2018从 模板字符串 中删除了转义序列的语法限制。Rest/Spread 属性
ES2015最有趣的功能之一是 扩展(spread)运算符。该运算符使复制和合并数组变得更加简单。可以使用
…
运算符,来代替concat()
或slice()
方法:在必须传入数组参数的情况下,扩展运算符也能派上用场。例如:
ES2018通过向对象添加扩展属性来进一步扩展此语法。可以将对象的自身可枚举属性复制到新对象上。在ES2018之前,尝试这样做会引发错误。如果有多个具有相同名称的属性,则将使用最后一个属性。如下:
扩展运算符还提供了一种合并两个或多个对象的新方法,可以将其用作
Object.assign()
的替代方法:注意,扩展运算符并不总是产生与
Object.assign()
相同的结果。例如:以上代码中,
Object.assign()
方法执行继承的setter属性。相反,扩展运算符完全忽略了setter。重要的是要记住,扩展运算符只复制自身的可枚举属性。在以下示例中,type属性不会被复制到目标对象中,因为其enumerable属性设置为false。
继承的属性会被忽略,即使它们是可枚举的:
扩展运算符为浅复制。如果对象的属性也是对象,则仅复制属性的对象引用:
ES2015增加的另一个有用功能是rest参数,它使JavaScript程序员能够使用...将值表示为数组。例如:
以上代码中,arr中的第一个值分配给x,其余值分配给rest。这种称为阵列解构的模式变得如此受欢迎,以至于Ecma技术委员会决定为对象带来类似的功能:
兼容性
Node: 8.3.0
异步迭代(Asynchronous Iteration)
迭代数据集是编程的重要部分。在ES2015之前,JavaScript为此提供了诸如
for
,for in
之类的语句,以及诸如map()
,filter()
和forEach()
之类的方法。为了使程序员能够一次一个地处理集合中的元素,ES2015引入了迭代器(iterator)接口。如果对象具有
Symbol.iterator
属性,则该对象是可迭代的。在ES2015中,如Set
,Map
和Array
具有Symbol.iterator
属性,因此是可迭代的。以下代码给出了如何使用可迭代对象的示例:默认情况下,普通对象不可迭代,但如果在其上定义Symbol.iterator属性,则它可以变为可迭代,如下例所示:
虽然以上代码没有问题,但却不必要地复杂化。幸运的是,使用
generator
函数可以大大简化过程:迭代器(iterator)的缺点是它们不适合表示异步数据源。 ES2018的补救解决方案是异步迭代器和异步迭代。异步迭代器与传统迭代器的不同之处在于,它不是以{value,done}的形式返回普通对象,而是返回满足{value,done}的promise。异步iterable定义一个返回异步迭代器的Symbol.asyncIterator方法(而不是Symbol.iterator)。
迭代可迭代对象(iterable)的一种简单方法是使用
for of
语句,但是for of
不能用于async iterables
,因为value和done不是同步确定的。出于这个原因,ES2018提供了for await of
语句。我们来看一个例子:兼容性
Node:10.0.0
Promise.prototype.finally
ES2018的另一个令人兴奋的补充是
finally()
方法。一些JavaScript库之前已经实现了类似的方法,这在许多情况下证明是有用的。这鼓励了Ecma技术委员会正式将finally()
添加到规范中。使用这种方法,程序员将能够执行一个代码块,而不管promise的成功与否。我们来看一个简单的例子:与
then()
和catch()
一样,finally()
方法总是返回一个promise,因此您可以链接更多方法。通常,您希望使用finally()
作为最后一个链,但在某些情况下,例如在发出HTTP请求时,将另一个catch()
链接起来处理finally()
中可能发生的错误是一种很好的做法。兼容性
Node:10.0.0
新的RegExp功能
ES2018为RegExp对象增加了四个新功能,进一步提高了JavaScript的字符串处理能力。这些功能如下:
s (dotAll) 模式
.
是正则表达式模式中的特殊字符,它匹配除换行符之外的任何字符。匹配所有字符(包括换行符)的解决方法是使用具有两个相反短字的字符类,例如[\d\D]
。此字符类告诉正则表达式引擎找到一个数字(\d)或非数字(\D)的字符。因此,它匹配任何字符:ES2018引入了一种模式,其中
.
可用于实现相同的结果。可以使用s标志在每个正则表达式的基础上激活此模式:命名捕获组
在一些正则表达式模式中,使用数字来引用捕获组可能会令人困惑。例如,取正则表达式
/(\d{4})-(\d{2})-(\d{2})/
与日期匹配。由于美式英语中的日期符号与英式英语不同,因此很难知道哪个组指的是哪一天,哪个组指的是月份:ES2018引入了使用
(?<name>...)
语法的命名捕获组。因此,匹配日期的模式可以用不那么模糊的方式编写:您可以使用
\k<name>
语法在模式中稍后调用命名的捕获组。例如,要在句子中找到连续的重复单词,可以使用/\b(?<dup>\w+)\s+\k<dup>\b/
:要将命名捕获组插入
replace()
方法的替换字符串,您需要使用$ <name>
语法。例如:后行断言
ES2018为JavaScript带来了后行断言,这些断言已经在其他正则表达式实现中可用多年。以前,JavaScript只支持先行断言。 后行断言用
(?<=...)
表示,使您能够根据模式之前的子字符串匹配模式。例如,如果您想要以美元,英镑或欧元匹配产品的价格而不捕获货币符号,则可以使用/(?<=\$|£|€)\d+(\.\d*)?/
:还有一个相反版本的lookbehind,用
(?<!...)
表示。允许您仅在模式不在后面的模式之前匹配模式。例如,模式/(?<!un)available/
匹配available
单词,如果它没有“un”前缀:Unicode属性转义
ES2018提供了一种称为Unicode属性转义的新类型转义序列,它在正则表达式中提供对完整Unicode的支持。假设您要在字符串中匹配Unicode字符㉛。虽然㉛被认为是一个数字,但是你不能将它与
\d
的速记字符类匹配,因为它只支持ASCII [0-9]
。Unicode属性转义可用于匹配Unicode中的任何十进制数:兼容性
Node:10.0.0
模板字符串修订
当模板字符串紧跟在函数名之后时,它被称为标记模板字符串。当您想要使用函数解析模板字符串时,标记模板字符串会派上用场。请考虑以下示例:
在ES2018之前,标记模板字符串具有与转义序列相关的语法限制。反斜杠后跟某些字符序列被视为特殊字符:
\x
被解释为十六进制转义符,\u
被解释为unicode转义符,\_
后跟被解释为八进制转义符的数字。因此,解释器将诸如C:\xxx\uuu
或\ubuntu
之类的字符串视为无效的转义序列,并将抛出SyntaxError。ES2018从模板字符串中删除了这些限制,而不是抛出错误,将无效转义序列表示为
undefined
:兼容性
Node:8.10.0
总结
我们已经仔细研究了ES2018中引入的几个关键特性,包括
asynchronous iteration
,rest/spread
属性,Promise.prototype.finally()
以及RegExp
对象的新增功能。虽然其中一些浏览器供应商尚未完全实现其中一些功能,但由于像Babel这样的JavaScript转换器,它们今天仍然可以使用。原文链接