ES9 新特性
在这里,我们将了解 ES9 中的新特性。 让我们从了解异步生成器开始。
异步生成器和迭代
可以使用 async
关键字使异步生成器异步。 定义异步生成器的语法如下:
async function* generator_name() {
//statements
}
示例
以下示例显示了一个异步生成器,它在每次调用生成器的 next()
方法时返回 Promise。
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))
上述代码输出结果如下
{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}
{value: undefined, done: true}
for await of 循环
异步迭代不能使用传统的 for..of
循环语法迭代,因为它们返回 promise 。 ES9 引入了 for await of
循环来支持异步迭代。
下面给出了使用 for await of
循环的语法,其中,
- 在每次迭代中,不同属性的值被分配给变量,并且变量可以用
const
、let
或var
声明。 - iterable - 要迭代其可迭代属性的对象。
for await (variable of iterable) {
statement
}
示例
以下示例显示了使用 for await of
循环来迭代异步生成器。
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')
上述代码输出结果如下
end of script
1
2
3
以下示例使用 for await of
循环迭代数组。
async function fntest(){
for await (const val of [10,20,30,40]){
console.log(val)
}
}
fntest();
console.log('end of script')
上述代码输出结果如下
end of script
10
20
30
40
Rest/Spread 属性
ES9 支持对对象使用 Rest
和 Spread
运算符。
示例:对象和 Rest 运算符
以下示例显示了对对象使用 rest
运算符。 student 的 age 属性的值被复制到 age 变量中,而其余属性的值被复制到使用 rest 语法“...”的另一个变量中。
const student = {
age:10,
height:5,
weight:50
}
const {age,...other} = student;
console.log(age)
console.log(other)
上述代码输出结果如下
10
{height: 5, weight: 50}
示例:对象和展开运算符
展开运算符可用于组合多个对象或克隆对象。 这在以下示例中显示
//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)
上述代码输出结果如下
{a: 10, b: 20}
{a: 10, b: 20, c: 30}
Promise: finally()
finally()
会在 promise 完成时执行,无论其结果如何。 这个函数返回一个承诺。 它可用于避免 promise 的 then()
和 catch()
处理程序中的代码重复。
语法
下面提到的语法是针对函数 finally()
的。
promise.finally(function() {
});
promise.finally(()=> {
});
示例
以下示例声明了一个异步函数,该函数在延迟 3 秒后返回正数的平方。 如果传递负数,该函数将抛出错误。 finally
块中的语句在任何一种情况下都会执行,无论 promise 是被拒绝还是已解决。
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");
上述代码输出结果如下
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: malformed Unicode character escape sequence
但是,与早期版本不同的是,ES9 将无效的 unicode
序列解析为 undefined 并且不会抛出错误。 这在以下示例中显示
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)
上述代码输出结果如下
{parsed: undefined}
{parsed: "❤️"}
原始字符串
ES9 引入了一个特殊的属性 raw,可用于标记函数的第一个参数。 此属性允许我们在输入原始字符串时访问它们,而无需处理转义序列。
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)
上述代码输出结果如下
{Parsed: undefined, Raw: "\unicode"}
{Parsed: "❤️", Raw: "\u2764\uFE0F"}
正则表达式功能
在正则表达式中,点运算符或句点用于匹配单个字符。 这 .
点运算符跳过换行符,如 \n
、\r
,如下例所示
console.log(/Fql.Jiyik/.test('Fql_Jiyik')); //true
console.log(/Fql.Jiyik/.test('Fql\nJiyik')); //false
console.log(/Fql.Jiyik/.test('Fql\rJiyik')); //false
正则表达式模式表示为 /regular_expression/
。 test()
方法接受一个字符串参数并搜索正则表达式模式。 在上面的示例中,test()
方法搜索以 Fql 开头的模式,后跟任何单个字符并以 Point 结尾。 如果我们在 Fql 和 Jiyik 之间的输入字符串中使用 \n 或 \r,则 test()
方法将返回 false。
true
false
false
ES9 引入了一个新标志 - DotAllFlag \s
,它可以与 Regex 一起使用来匹配行终止符和表情符号。 这在以下示例中显示
console.log(/Fql.Jiyik/s.test('Fql\nJiyik'));
console.log(/Fql.Jiyik/s.test('Fql\rJiyik'));
上述代码输出结果如下
true
true
命名捕获组
在 ES9 之前,捕获组是通过索引访问的。 ES9 允许我们为捕获组分配名称。 下面给出了相同的语法
(?<Name1>pattern1)
示例
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