ES9 - 新功能
在这里,我们将了解 ES9 中的新功能。让我们从了解异步生成器开始。
异步生成器和迭代
可以使用 async 关键字将异步生成器变为异步。定义异步生成器的 语法 如下所示 −
async function* generator_name() {
//statements
}
示例
以下示例展示了一个异步生成器,它在每次调用生成器的 next() 方法时返回 Promise。
<script>
async function* load(){
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
let l = load();
l.next().then(r=>console.log(r))
l.next().then(r=>console.log(r))
l.next().then(r=>console.log(r))
l.next().then(r=>console.log(r))
</script>
上述代码的输出将如下所示 −
{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}
{value: undefined, done: true}
for await of loop
异步可迭代对象无法使用传统的 for..of loop 语法进行迭代,因为它们返回的是Promise。ES9 引入了 for await of loop 来支持异步迭代。
使用 for await of loop 的语法如下,其中,
每次迭代时,都会将不同属性的值分配给 variable,并且可以使用 const、let 或 var 声明变量。
- iterable −需要迭代其可迭代属性的对象。
for await (variable of iterable) {
语句
}
示例
以下示例显示了如何使用 for await of 循环来迭代异步生成器。
<script>
async function* load(){
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
async function test(){
for await (const val of load()){
console.log(val)
}
}
test();
console.log('end of script')
</script>
上述代码的输出将如下所示 −
end of script 1 2 3
示例
以下示例使用 for await of 循环迭代数组。
<script>
async function fntest(){
for await (const val of [10,20,30,40]){
console.log(val)
}
}
fntest();
console.log('end of script')
</script>
上述代码的输出将如下所示 −
end of script 10 20 30 40
Rest/Spread 属性
ES9 支持将 Rest 和 Spread 运算符与对象一起使用。
示例:对象和 Rest 运算符
以下示例显示了将 rest 运算符与对象一起使用。student 的 age 属性值被复制到 age 变量中,而其余属性的值则使用 rest 语法 `...` 复制到另一个变量中。
<script>
const student = {
age:10,
height:5,
weight:50
}
const {age,...other} = student;
console.log(age)
console.log(other)
</script>
上述代码的输出如下所示 −
10
{height: 5, weight: 50}
示例:对象和扩展运算符
扩展运算符可用于组合多个对象或克隆对象。如以下示例所示 −
<script>
//spread operator
const obj1 = {a:10,b:20}
const obj2={c:30}
//clone obj1
const clone_obj={...obj1}
//combine obj1 and obj2
const obj3 = {...obj1,...obj2}
console.log(clone_obj)
console.log(obj3)
</script>
上述代码的输出将如下所示 −
{a: 10, b: 20}
{a: 10, b: 20, c: 30}
Promise:finally()
只要Promise得到解决,就会执行 finally(),无论其结果如何。此函数返回一个Promise。它可用于避免Promise的 then() 和 catch() 处理程序中的代码重复。
语法
下面提到的语法适用于函数 finally()。
promise.finally(function() {
});
promise.finally(()=> {
});
示例
以下示例声明了一个异步函数,该函数在延迟 3 秒后返回正数的平方。如果传递的是负数,该函数将抛出错误。无论Promise是被拒绝还是被解决,finally 块中的语句都会在任一情况下执行。
<script>
let asyncSquareFn = function(n1){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(n1>=0){
resolve(n1*n1)
}
else reject('NOT_POSITIVE_NO')
},3000)
})
}
console.log('Start')
asyncSquareFn(10)//modify to add -10
.then(result=>{
console.log("result is",result)
}).catch(error=>console.log(error))
.finally(() =>{
console.log("inside finally")
console.log("executes all the time")
})
console.log("End");
</script>
上述代码的输出将如下所示
Start End //after 3 seconds result is 100 inside finally executes all the time
模板字面量修订
从 ES7 开始,标记模板符合以下转义序列的规则 −
Unicode 转义序列使用 "\u" 表示,例如 \u2764\uFE0F
Unicode 代码点转义序列使用 "\u{}" 表示,例如 \u{2F>
十六进制转义序列使用 "\x" 表示,例如\xA8
八进制文字转义序列使用""表示,后跟一个或多个数字,例如 \125
在 ES2016 及更早版本中,如果将无效的转义序列与标记函数一起使用,则会引发语法错误,如下所示 −
//带有无效 unicode 序列的标记函数 myTagFn`\unicode1` // SyntaxError:格式错误的 Unicode 字符转义序列
但是,与早期版本不同,ES9 将无效的 unicode 序列解析为未定义,并且不会引发错误。这在下面的示例中显示 −
<script>
function myTagFn(str) {
return { "parsed": str[0] }
}
let result1 =myTagFn`\unicode1` //invalid unicode character
console.log(result1)
let result2 =myTagFn`\u2764\uFE0F`//valid unicode
console.log(result2)
</script>
上述代码的输出将如下所示 −
{parsed: undefined}
{parsed: "❤️"}
原始字符串
ES9 引入了一个特殊属性 raw,可用于标记函数的第一个参数。此属性允许您访问输入的原始字符串,而无需处理转义序列。
示例
<script>
function myTagFn(str) {
return { "Parsed": str[0], "Raw": str.raw[0] }
}
let result1 =myTagFn`\unicode`
console.log(result1)
let result2 =myTagFn`\u2764\uFE0F`
console.log(result2)
</script>
上述代码的输出将如下所示 −
{Parsed: undefined, Raw: "\unicode"}
{Parsed: "❤️", Raw: "\u2764\uFE0F"}
正则表达式功能
在正则表达式中,点运算符或句点用于匹配单个字符。. 点运算符 跳过换行符,如 , ,如下例所示 −
console.log(/Tutorials.Point/.test('Tutorials_Point')); //true
console.log(/Tutorials.Point/.test('Tutorials
Point')); //false
console.log(/Tutorials.Point/.test('Tutorials
Point')); //false
正则表达式模式表示为 / regular_expression /。 test() 方法采用字符串参数并搜索正则表达式模式。在上面的例子中,test() 方法 搜索以 Tutorials 开头,后跟任意单个字符并以 Point 结尾的模式。如果我们在 Tutorials 和 Point 之间的输入字符串中使用 或 ,则 test() 方法将返回 false。
true false false
ES9 引入了一个新标志 - DotAllFlag (\s),可与 Regex 一起使用来匹配行终止符和表情符号。以下示例 − 显示了这一点
console.log(/Tutorials.Point/s.test('Tutorials
Point'));
console.log(/Tutorials.Point/s.test('Tutorials
Point'));
上述代码的输出将概要 −
true true
命名捕获组
在 ES9 之前,捕获组是通过索引访问的。ES9 允许我们为捕获组分配名称。相同的语法如下 −
(?<Name1>pattern1)
Example
const birthDatePattern = /(?<myYear>[0-9]{4})-(?<myMonth>[0-9]{2})/;
const birthDate = birthDatePattern.exec('1999-04');
console.log(birthDate.groups.myYear);
console.log(birthDate.groups.myMonth);
上述代码的输出如下所示 −
1999 04

