- ES6 教程
- ES6 - 首页
- ES6 - 概述
- ES6 - 环境
- ES6 - 语法
- ES6 - 变量
- ES6 - 运算符
- ES6 - 决策
- ES6 - 循环
- ES6 - 函数
- ES6 - 事件
- ES6 - Cookies
- ES6 - 页面重定向
- ES6 - 对话框
- ES6 - Void 关键字
- ES6 - 页面打印
- ES6 - 对象
- ES6 - 数字
- ES6 - 布尔值
- ES6 - 字符串
- ES6 - Symbol
- ES6 - 新的字符串方法
- ES6 - 数组
- ES6 - 日期
- ES6 - 数学
- ES6 - 正则表达式
- ES6 - HTML DOM
- ES6 - 迭代器
- ES6 - 集合
- ES6 - 类
- ES6 - Maps 和 Sets
- ES6 - Promises
- ES6 - 模块
- ES6 - 错误处理
- ES6 - 对象扩展
- ES6 - Reflect API
- ES6 - Proxy API
- ES6 - 验证
- ES6 - 动画
- ES6 - 多媒体
- ES6 - 调试
- ES6 - 图片地图
- ES6 - 浏览器
- ES7 - 新特性
- ES8 - 新特性
- ES9 - 新特性
- ES6 有用资源
- ES6 - 快速指南
- ES6 - 有用资源
- ES6 - 讨论
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 循环
异步可迭代对象不能使用传统的 **for..of 循环** 语法进行迭代,因为它们返回 Promise。ES9 引入了 **for await of 循环** 来支持 **异步迭代**。
使用 **for await of 循环** 的语法如下所示,其中:
在每次迭代中,一个不同属性的值被赋值给 **变量**,并且变量可以用 const、let 或 var 声明。
- **iterable** - 要迭代其可迭代属性的对象。
for await (variable of iterable) { statement }
示例
以下示例演示了如何使用 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
剩余/扩展属性
ES9 支持在对象中使用剩余和扩展运算符。
示例:对象和剩余运算符
以下示例演示了如何在对象中使用剩余运算符。student 的 age 属性的值被复制到 age 变量中,而其余属性的值使用剩余语法 `...` 复制到 other 变量中。
<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。它可以用于避免在 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 及更早版本中,如果带标记函数使用无效转义序列,则会抛出语法错误,如下所示:
//tagged function with an invalid unicode sequence myTagFn`\unicode1` // SyntaxError: malformed Unicode character escape sequence
但是,与早期版本不同,ES9 将无效的 Unicode 序列解析为 undefined,并且不会抛出错误。这在以下示例中显示:
<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"}
正则表达式特性
在正则表达式中,点运算符或句点用于匹配单个字符。**. 点运算符** 跳过换行符,如 **\n、\r**,如下例所示:
console.log(/Tutorials.Point/.test('Tutorials_Point')); //true console.log(/Tutorials.Point/.test('Tutorials\nPoint')); //false console.log(/Tutorials.Point/.test('Tutorials\rPoint')); //false
正则表达式模式表示为 / **regular_expression /。**test() 方法接受一个字符串参数并搜索正则表达式模式。在上面的示例中,**test() 方法** 搜索以 Tutorials 开头、后跟任何单个字符并以 Point 结尾的模式。如果我们在 Tutorials 和 Point 之间的输入字符串中使用 **\n** 或 **\r**,则 test() 方法将返回 false。
true false false
ES9 引入了一个新的标志 - **DotAllFlag (\s)**,它可以与 Regex 一起使用以匹配行终止符和表情符号。这在以下示例中显示:
console.log(/Tutorials.Point/s.test('Tutorials\nPoint')); console.log(/Tutorials.Point/s.test('Tutorials\rPoint'));
以上代码的输出将如下所示:
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