ES2021 新特性!

Daotin發表於2021-07-10

大家好,我是前端隊長Daotin,想要獲取更多前端精彩內容,關注我(全網同名),解鎖前端成長新姿勢。

以下正文:

2021 年 6 月 22 日,第 121 屆 Ecma 國際(Ecma International)大會以遠端會議形式召開。正式通過了ES2021標準,ECMAScript 2021 (ES12)成為事實的 ECMAScript 標準。

本文簡要介紹了 JavaScript 今年新加了哪些語法,還好不是很多。

主要有5個新特性:

邏輯賦值運算子
數字分隔符
Promise.any & AggregateError
String.prototype.replaceAll
WeakRefs & FinalizationRegistry物件

邏輯賦值運算子

??= &&= 和 ||=

??= 的判斷邏輯和 ?? 一致,左值為 null 或 undefined 時返回右值,否則返回左值。

不同的是 ??= 包含向左值賦值的操作。類比于于+= -= 中的等號。

// 舊
let a = null;
a = a ?? 'daotin';
a = a && 'daotin';
a = a || 'daotin';

// 新
let a = null;
a ??= 'daotin';
a &&= 'daotin';
a ||= 'daotin'; 

數字分隔符

允許數值字面量中間包含不連續_ ,以提高可讀性。

1_000_000_000           // Ah, so a billion
101_475_938.38          // And this is hundreds of millions

let a = 1_1; // 11
let a = 1__1 // 錯誤,只允許一個下劃線作為數字分隔符
let a = 1_;  // 錯誤,分隔符不能在尾部 
let a = _1;  // 錯誤,分隔符不能在頭部 

Number(1_1); // 11
Number('1_1'); // NaN

注意:分隔符不能在尾部和頭部,只能在數字之間,只允許一個下劃線作為數字分隔符,不可連續。分隔符不影響數值的型別轉換值,也無法在字串轉數值時被識別。

Promise.any & AggregateError

Promise.any 方法:any 接受 Promise 陣列作為引數,返回合成的 Promise。只要給定的迭代中的一個 promise 成功,就採用第一個 promise 的值作為它的返回值,

const promises = [
  fetch('/endpoint-a').then(() => 'a'),
  fetch('/endpoint-b').then(() => 'b'),
  fetch('/endpoint-c').then(() => 'c'),
];
try {
  const first = await Promise.any(promises);
  // Any of the promises was fulfilled.
  console.log(first);
  // → e.g. 'b'
} catch (error) {
  // All of the promises were rejected.
  console.assert(error instanceof AggregateError);
  // Log the rejection values:
  console.log(error.errors);
  // → [
  //     <TypeError: Failed to fetch /endpoint-a>,
  //     <TypeError: Failed to fetch /endpoint-b>,
  //     <TypeError: Failed to fetch /endpoint-c>
  //   ]
}

此程式碼示例檢查哪個端點響應最快,然後將其記錄下來。只有當 所有 請求都失敗時,我們才最終進入程式碼 catch 塊,然後在其中處理錯誤。

多個 Promise 例項,包裝成一個新的 Promise 例項:

名稱 描述
all 只要一個 Promise 失敗,立即返回失敗,全成功返回成功陣列
race ace是比賽、競賽的意思,所以顧名思義,就是看誰快,就返回誰。只要一個 Promise 完成就返回結果(無論成功失敗)
any 只要一個 Promise 成功,立即返回成功,全失敗返回 AggregateError
allSettled 所有 Promise 完成才返回(無論成功失敗),返回結果陣列

String.prototype.replaceAll

相比於String.prototype.replace,如果不使用全域性正規表示式,就無法替換字串中子字串的所有例項。只會替換第一次匹配的字元。

'hello world'.replace('o', '_'); // hell_ world

'hello world'.replace(/o/g, '_'); // hell_ w_rld

'hello world'.replaceAll('o', '_'); // hell_ w_rld

WeakRefs & FinalizationRegistry物件

一般來說,在JavaScript中,物件的引用是強引用的,這意味著只要持有物件的引用,它就不會被垃圾回收。只有當該物件沒有任何的強引用時, js引擎垃圾回收器才會銷燬該物件並且回收該物件所佔的記憶體空間。

let obj = {a:1, b:2}; // 只要我們訪問 obj 物件,這個物件就不會被垃圾回收

但是 WeakRefs 可以建立一個弱引用,物件的弱引用是指當該物件應該被 js引擎垃圾回收器回收時不會阻止垃圾回收器的回收行為。

Weakref 例項具有一個方法 deref,該方法返回被引用的原始物件,如果原始物件已被收集,則返回 undefined 物件。

const ref = new WeakRef({ name: 'daotin' });
let obj = ref.deref();
if (obj) {
  console.log(obj.name); // daotin
} 

注意:正確使用它們需要仔細考慮,如果可能,最好避免使用它們。

使用 FinalizationRegistry 物件可以在垃圾回收器回收物件時執行回撥函式。

// 構建監聽物件被垃圾回收器清除的回撥
const registry = new FinalizationRegistry(heldValue => {
      console.log('----', heldValue);
});

const obj = {};
const token = {};

// 註冊監聽
registry.register(obj, "obj deleted!", token);

// 取消監聽
registry.unregister(token);

// 可能很久以後,回撥執行
// ---- obj deleted!

register 引數分別為:

•需要監聽的物件•執行回撥函式的引數•取消監聽用的識別符號

參考連結:

https://h3manth.com/ES2021
https://juejin.cn/post/6978514117006983176

https://mp.weixin.qq.com/s/pRkTLu6mocANvl8UDwZPwg#at

--- End ---

你好,我是前端隊長Daotin,專注分享前端與認知。希望在這裡,和你分享我的前端學習和工作經驗,記錄個人成長。

以上,如果你看了覺得對你有所幫助,就點個贊叭,這樣隊長也有更新下去的動力,跪謝各位父老鄉親啦~~~ 聽說喜歡點讚的人,一個月內都會有好運降臨哦 ~~

image