- 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