1.通過 # 給 class 添加私有變量
class Counter {
#number = 10
increment() {
this.#number++
}
getNum() {
return this.#number
}
}
const counter = new Counter()
counter.increment()
console.log(counter.getNum()) //11
console.log(counter.#number) //SyntaxError
在 ES2020 中,通過 #
可以給 class 添加私有變量。在 class 的外部我們無法獲取該值。當我們嘗試輸出 counter.#number
,語法錯誤被拋出:無法在 class Counter
外部獲取它。這樣就不需要使用閉包來隱藏不想暴露給外界的私有變量。BigInt
2.BigInt
Js 中 Number類型只能安全的表示-(2^53-1)至 2^53-1 範的值,超出這個範圍的整數計算或者表示會丟失精度,我們可以用 BigInt 對象表示不在這個範圍內的數。可以通過常規操作進行加、減、乘、除、餘數和冪等運算。它可以由數字和十六進制或二進制字符串構造。此外它還支持 AND、OR、NOT 和 XOR 之類的按位運算。唯一無效的位運算是零填充右移運算符(>>>)。
使用BigInt 有兩種方式:1.在整數字面量後面加n。2. BigInt 函數。
let a = 123n;
let b = BigInt(456n);
console.log(typeof a) //bigint
console.log(a+b) //579n
1n == 1 //true
1n === 1 //false
3.空值合併運算符
來自 undefined 或 null 值的另一個問題是,如果我們想要的變量爲 undefined 或 null 則必須給變量設置默認值。例如:
const a = b || 123;
當使用 || 運算符將 b 設置爲 a 時,如果 b 被定義爲 undefined,我們必須設置一個默認值。運算符 || 的問題在於,所有類似於 0,false 或空字符串之類的值都將被我們不想要的默認值覆蓋。
爲了解決這個問題,創建了“nullish”合併運算符,用 ?? 表示。有了它,我們僅在第一項爲 null 或 undefined 時設置默認值。使用無效的合併運算符,以上表達式將變爲:
const a = b ?? 123;
4.可選鏈運算符
如果要訪問對象的深層嵌套屬性,則必須通過很長的布爾表達式去檢查每個嵌套級別中的屬性。必須檢查每個級別中定義的每個屬性,直到所需的深度嵌套的屬性爲止,如下代碼所示:
let name = user && user.info && user.info.name;
let age = user && user.info && user.info.getAge && user.info.getAge();
如果在任何級別的對象中都有 undefined 或 null 的嵌套對象,如果不進行檢查,那麼的程序將會崩潰。這意味着我們必須檢查每個級別,以確保當它遇到 undefined 或 null 對象時不會崩潰。
使用可選鏈運算符,只需要使用 ?. 來訪問嵌套對象。而且如果碰到的是 undefined 或 null 屬性,那麼它只會返回 undefined。通過可選鏈,可以把上面的代碼改爲:
let name = user?.info?.name;
let age = user?.info?.getAge?.();
5.Promise.allSettled()
Promise.allSettled(iterable);
iterable:一個可迭代的對象,例如Array,其中每個成員都是Promise。
返回一個在所有給定的promise resolved 或者 rejected的promise,並帶有一個對象數組,每個對象表示對應的promise結果。
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result.status)));
// expected output:
// "fulfilled"
// "rejected"
6.dynamic-import
靜態 import 和動態 import()
有各自的特點和使用場景。使用靜態 import
來初始繪製依賴關係,考慮到按需加載則使用動態 import()
。
static import 是沒有括號的,dynamic import() 是帶括號的。不注意的可能會混淆。用法的區別:
static import: import xxx from 'xxx' //有聲明提升,一般只放在頭部位置
dynamic import(): const xxx = import('xxx') //可以放在任何位置
el.onclick = () => {
import(`main.js`)
.then(() => {
//...
})
}
7.globalThis
globalThis
提供了一個標準的方式去獲取不同環境下的全局對象。它不像 window
或者 self
這些屬性,而是確保可以在有無窗口的環境下都可以正常工作。所以你可以安心的使用 globalThis
,不必擔心它的運行環境。
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
var globals = getGlobal();
if (typeof globals.setTimeout !== 'function') {
// no setTimeout in this environment!
}
//有了 globalThis 之後,只需要:
if (typeof globalThis.setTimeout !== 'function') {
// no setTimeout in this environment!
}
參考資料:
https://github.com/tc39/proposals/blob/master/finished-proposals.md