ES2018规范引入了四个新特性。这些功能包括异步迭代、rest/spread属性、Promise.prototype.finally()和正则表达式改进。这个问题将帮助您了解这些ES2018功能如何工作以及如何使用它们。异步迭代异步迭代是讨论较少的ES2018特性之一。虽然有很多关于ES2018其他特性的讨论,但几乎没有关于异步迭代的讨论。通过异步迭代,我们可以获得异步的可迭代对象和迭代器。这意味着您可以将await关键字与for...of循环一起使用。您可以使用这些循环来迭代可迭代对象。可迭代对象包括数组、映射、集合、NodeLists、函数参数、TypedArray等。在ES2018之前,for...of循环是同步的。如果您尝试遍历涉及异步操作的可迭代对象并等待,它将无法工作。循环本身保持同步,基本上忽略await,并在其中的异步操作完成之前完成迭代。//下面的代码在ES2018之前无法运行,因为循环保持同步。//创建一个异步函数:asyncfunctionprocessResponses(someIterable){//遍历可迭代对象for(letitemofsomeIterable){//通过异步操作处理items,比如promise:awaitprocessItem(item)}}还有for...of循环可以与异步代码一起使用。也就是说,可以在遍历可迭代对象的同时,进行一些异步操作。for...of循环将是异步的,允许您等待异步操作完成。要记住的是在哪里使用await关键字。没必要放在循环体内,应该放在for...of关键字中的for之后。现在当你使用next()方法获取异步迭代器的下一个值时,你将得到一个Promise。如果您想了解更多信息,可以在GitHub(https://github.com/tc39/proposal-async-iteration)上查看。//创建一个异步函数:asyncfunctionprocessResponses(someIterable){//遍历iterable并等待异步操作的结果forawait(letitemofsomeIterable){processItem(item)}}Rest/Spread属性rest和spread并不是真正的新特征。两者都是在ES6中作为新的运算符引入的,并迅速流行起来。可以说JavaScript程序员喜欢它们。唯一的问题是它们只能用在数组和参数上,但是ES2018将这两个功能带到了对象上。rest和spread运算符的语法都非常简单,由三个点(...)组成。在这些点之后是使用rest或spread运算符的对象。让我们简要讨论一下这两者是如何工作的。对象的rest运算符rest运算符允许您将对象的所有剩余对象属性提取到新对象上。请注意,这些属性必须是可枚举的。如果您对某些属性使用了分解,则剩余运算符将只提取剩余的属性。//Restexample:constdaysObj={one:'Monday',two:'Tuesday',three:'Wednesday',four:'Thursday',five:'Friday'}//使用解构为变量的前两个属性赋值到变量。//然后,使用rest将其余属性赋给第三个变量。const{one,two,...restOfDays}=daysObj//rest只提取“three”、“four”和“five”//因为我们已经提取了“one”和“two”console.log(one)//Output://'Monday'console.log(two)//Output://'Tuesday'console.log(restOfDays)//Output://{three:'Wednesday',four:'Thursday',five:'Friday'}如果你想在对象上使用剩余操作符,你需要记住两件事:首先,你只能使用它一次,除非你在嵌套对象上使用它。其次,它必须最后使用。这就是为什么在上面的示例中,它是在解构前两个属性之后而不是之前看到的。//这行代码不起作用,因为在顶部使用了剩余运算符:const{...all,one,two}={one:1,two:2,three:3}//Thislineworks:const{one,two,...all}={one:1,two:2,three:3}//这行不起作用,因为同一层有多个剩余运算符:const{one,...some,...end}={/*someproperties*/}//这一行有效,多层次的多个rest运算符:const{one,{...secondLevel},...firstLevel}={/*someproperties*/}objectspreadoperatorspread运算符的作用是通过插入另一个对象的所有属性来创建一个新对象。Spread运算符还允许您插入多个对象的属性。您还可以将此运算符与添加新属性结合使用。//Spreadexample:constmyOriginalObj={name:'JoeDoe',age:33}//使用展开运算符创建一个新对象:constmyNewObj={...myOriginalObj}console.log(myNewObj)//Output://{name:'JoeDoe',age:33}//添加属性的示例:constmyOriginalObj={name:'Caesar'}//使用展开运算符创建一个新对象//并添加一个新属性“genre”:constmyNewObj={...myOriginalObj,genre:'Strategy'}console.log(myNewObj)//Output://{//name:'Caesar',//genre:'Strategy'////展开运算符并合并两个对象:constmyObjOne={title:'EloquentJavaScript'}constmyObjTwo={author:'MarijnHaverbeke'}constmyNewObj={...myObjOne,...myObjTwo}console.log(myNewObj)//Output://{//title:'EloquentJavaScript',//author:'MarijnHaverbeke'//}从多个对象插入属性并添加新对象时,顺序很重要。让我解释一下,假设您想使用扩展运算符基于两个现有对象创建一个新对象。第一个现有对象包含具有某个值的属性标题。第二个对象也包含属性title,但具有不同的值。最终取哪个称号?答案是最后一个。如果在第一个对象上使用扩展运算符,然后在第二个对象上使用,则第二个标题将生效。如果对第二个对象应用扩展运算符,第一个标题将生效。//传播运算符并合并两个对象:constmyObjOne={title:'EloquentJavaScript',author:'MarijnHaverbeke',}constmyObjTwo={title:'YouDon\'tKnowJSYet',language:'English'}//用传播操作创建一个通过组合“myObjOne”和“myObjTwo”创建新对象//注意:“myObjTwo”中的“title”将覆盖“myObjTwo”的“title”//因为“myObjTwo”排在最后。constmyNewObj={...myObjOne,...myObjTwo}console.log(myNewObj)//Output://{//title:"YouDon'tKnowJSYet",//author:'MarijnHaverbeke',//language:'英语'////注意:“myObjOne”中的“title”将覆盖“myObjTwo”中的“title”constmyNewObj={...myObjTwo,...myObjOne}console.log(myNewObj)//Output://{//title:'EloquentJavaScript',//language:'English',//author:'MarijnHaverbeke'//}Promise.prototype.finally()最初有两个Promise的回调函数。其中之一是then(),它实现了Promise执行。第二个是catch(),当promise被拒绝或者then()抛出异常时执行。ES2018为Promises添加了第三个回调函数finally()。finally()回调在每次履行承诺时执行,无论承诺是否履行。此回调的一般用途是执行应该始终发生的操作。例如关闭模态对话框、关闭数据库连接或进行一些清理。//finally()示例:fetch().then(response=>response.json()).then(data=>console.log(data)).catch(error=>console.log(error))//最后做点事情:.finally(()=>console.log('Operationdone.'))对正则表达式的改进ES2018也对正则表达式函数做了一些改进。这些改进包括s(dotAll)标志、linebehind断言、命名捕获组和unicode属性转义。s(dotAll)首先是s(dotAll)。与点(.)不同,s(dotAll)允许匹配换行符和表情符号。//s(dotAll)示例:/hello.world/.test('hello\nworld')//Output://false/hello.world/s.test('hello\nworld')//Output://truelookbehindassertion在ES2018之前,JavaScript只支持lookahead断言。前瞻断言用于根据后面的文本匹配模式。ES2018中添加了对lookbehind断言的支持。它允许基于模式之前的文本模式进行匹配。后向断言的语法是?<=。//后行断言示例:/(?<=green)apple/.test('Oneredappleisonthetable.')//Output://false/(?<=green)apple/.test('Onegreenappleisonthetable.')//在Output://true断言之后还有一个反向回溯。仅当子字符串前面没有断言时,此断言才与模式匹配。否定后向断言的语法是?。constdate_pattern=/(?
