
- 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