ECMAScript 2021(ES12)新特性簡介

flydean發表於2021-09-22

簡介

ES12是ECMA協會在2021年6月發行的一個版本,因為是ECMAScript的第十二個版本,所以也稱為ES12.

ES12發行到現在已經有一個月了,那麼ES12有些什麼新特性和不一樣的地方呢?一起來看看吧。

基本上ES12引入了replaceAll方法用於對String進行操作,Promise.any用於對Promise進行組合操作,AggregateError用於表示多個錯誤的集合,新的邏輯操作符??=, &&=, ||=,弱引用WeakRef,FinalizationRegistry用於垃圾回收的註冊,一個數字的分隔符1_000,更加精準的陣列sort方法Array.prototype.sort。

下面本文將會一一進行講解。

replaceAll

熟悉java的朋友應該都知道,java中有兩個進行字串替換的方法,分別是replace和replaceAll,他們的區別在於replace是替換字串,而replaceAll是進行正規表示式匹配。

但是在javascript中兩者的涵義有所不同,在JS中replace是替換第一個出現的字串,而replaceAll就是字面上的意思替換所有的字串,我們舉個例子:

const string="flydean is a good fly"
console.log(string.replace("fly", "butterfly"));

上面的值返回:

butterflydean is a good fly

如果改用replaceAll:

const string="flydean is a good fly"
console.log(string.replaceAll("fly", "butterfly"));
butterflydean is a good butterfly

私有方法

自從JS有了類的概念之後,就可以在類中定義方法,並通過例項化之後的類進行呼叫,如下所示:

class Student {
  getAge() {
    console.log("永遠18歲")
  }
}

student= new Student();
student.getAge();

上面程式碼執行結果:

"永遠18歲"

但是如果我們不希望getAge()方法直接暴露給外部使用,也就是說希望getAge()是一個私有方法,那麼只需要在方法前面加上#即可。

class Student {
  #getAge() {
    console.log("永遠18歲")
  }
}

student= new Student();
student.getAge();

同樣執行,那麼會得到下面的錯誤提示:

Error: student.getAge is not a function

怎麼處理呢?我們知道私有方法是可以在方法內部呼叫的,那麼只需要建立一個公有方法,然後在這個公有方法中呼叫私有方法即可,如下所示:

class Student {
  #getAge() {
    console.log("永遠18歲")
  }
  
  getPublicAge(){
    this.#getAge();
  }
 
}

student= new Student();
student.getPublicAge();

我們可以得到同樣的結果。

私有屬性

上面講到了私有方法,那麼對於私有屬性是怎處理的呢?

通常,對於屬性,我們可以以get修飾符來進行修飾,然後就可以直接通過屬性名來訪問了:

class Student {
  get Age() {
    return 18;
  }
 
}

student= new Student();
console.log(student.Age);

結果我們會得到18這個輸出。

同樣,可以在屬性名前面加上#,讓其變成私有變數,如下所示:

class Student {
  get #Age() {
    return 18;
  }
 
}

student= new Student();
console.log(student.Age);

上面程式碼將會輸出undefined。

要想訪問上述的私有屬性,則可以用公有屬性去呼叫私有屬性方法:

class Student {
  get #Age() {
    return 18;
  }
   get publicAge() {
    return this.#Age
  }
}

student= new Student();
console.log(student.publicAge);

非常好用。

Promise.any() 和 AggregateError

promise.any可以返回任意一個提前resolve的結果,在現實的應用中,這種情況是非常常見的,我們來模擬一個例子:

const prom1 = new Promise((resolve, reject) => {
  setTimeout(
    () => resolve("promise one"),
    Math.floor(Math.random() * 100)
  );
});
const prom2 = new Promise((resolve, reject) => {
  setTimeout(
    () => resolve("promise two"),
    Math.floor(Math.random() * 100)
  );
});
const prom3 = new Promise((resolve, reject) => {
  setTimeout(
    () => resolve("promise three"),
    Math.floor(Math.random() * 100)
  );
});

(async function() {
  const result = await Promise.any([prom1, prom2, prom3]);
  console.log(result); 
})();

上述程式碼可以隨機輸出promise one,promise two,promise three。

如果將上述程式碼改成所有的都reject,那麼會丟擲AggregateError:

const prom1 = new Promise((resolve, reject) => {
  setTimeout(
    () => reject("promise one rejected"),
    Math.floor(Math.random() * 100)
  );
});
const prom2 = new Promise((resolve, reject) => {
  setTimeout(
    () => reject("promise two rejected"),
    Math.floor(Math.random() * 100)
  );
});
const prom3 = new Promise((resolve, reject) => {
  setTimeout(
    () => reject("promise three rejected"),
    Math.floor(Math.random() * 100)
  );
});

try{
(async function() {
  const result = await Promise.any([prom1, prom2, prom3]);
  console.log(result); 
})();
} catch(error) {
  console.log(error.errors);
}

報的錯如下:

Uncaught (in promise) AggregateError: No Promise in Promise.any was resolved
注意,必須是所有的promise都被reject之後才會丟擲AggregateError,如果有部分成功,那麼將會返回成功的結果。

數字分隔符

這個新特性是為了方便程式設計師看程式碼而出現的,如果數字比較大,那麼看起來就不是那麼一目瞭然,比如下面的長數字:

const number= 123456789;

一眼看不出這個數字的體量到底是多大,所以ES12提供了數字分隔符_。

分隔符不僅可以分割十進位制,也可以分割二淨值或者十六淨值的資料,非常好用。

const number = 1_000_000_000_000;
const binary = 0b1010_0101_1111_1101;
const hex = 0xAF_BF_C3;

上面例子分別代表了十進位制,二進位制和十六進位制的資料,非常直觀好用。

新的邏輯操作符

我們知道&& 和 || 是被來進行邏輯操作的運算子。

比如:

1 && 2 
1 || 2 

等操作,ES12提供了&& 和||的二元操作符,如下:

var x = 1;
var y = 2;
x &&= y;
x ||= y;

另外還提供了??的二元操作符,如:

var x;
var y = 2;
x ??= y;

上面程式碼的意思是,判斷x是不是空,如果是空那麼將y的值賦給x。

總結

ES12的幾個新特性還是挺實用的,大家可以嘗試一下。

本文已收錄於 http://www.flydean.com/ecmascript-12/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!

相關文章