JavaScript中新的強大功能:類中的私有字段,可選鏈,無效的合併運算符和BigInts。javascript
做者:John Au-Yeung前端
翻譯:瘋狂的技術宅java
原文:levelup.gitconnected.com/new-feature…git
未經容許嚴禁轉載前端工程化
自 2015 年發佈 ES6 以來,JavaScript 一直在快速發展,每次迭代中都會出現大量新功能。 JavaScript 語言規範的新版本每一年更新一次,新語言功能建議的定稿比以往更快。這意味着新功能將之前所未有的速度被整合到現代瀏覽器和其餘 JavaScript 運行時引擎(如 Node.js)中。數組
在 2019年,「Stage 3」階段有許多新功能,這意味着它即將完成,而且已經在瀏覽器和 Node 中得到對這些功能的支持。若是咱們想將它們用於生產環境,則可使用 Babel 之類的東西將其轉換爲舊版 JavaScript,以便在須要時用於舊版瀏覽器(如 Internet Explorer)。瀏覽器
在本文中,咱們研究了類中的私有字段,可選鏈,無效合併運算符和BigInts。安全
最新提案之一是在類中添加私有變量的方法。咱們將使用 #
符號表示類的私有變量。這樣就不須要使用閉包來隱藏不想暴露給外界的私有變量。例如咱們能夠編寫一個簡單的類來增長和減小數字,請看如下代碼:閉包
class Counter {
#x = 0; increment() {
this.#x++;
} decrement() {
this.#x--;
} getNum(){
return this.#x;
}
}const c = new Counter();
c.increment();
c.increment();
c.decrement();
console.log(c.getNum());
複製代碼
代碼中 console.log
輸出的結果是 1。 #x
是一個私有變量,沒法在類外部訪問。因此若是咱們這樣寫:函數
console.log(c.#x);
複製代碼
將會獲得提示 Uncaught SyntaxError: Private field '#x'
。
私有變量是 JavaScript 類很是須要的功能。如今,最新版本的 Chrome 和 Node.js v12 中已提供了此功能。
當前,若是要訪問對象的深層嵌套屬性,則必須經過很長的布爾表達式去檢查每一個嵌套級別中的屬性。必須檢查每一個級別中定義的每一個屬性,直到所需的深度嵌套的屬性爲止,以下代碼所示:
const obj = {
prop1: {
prop2: {
prop3: {
prop4: {
prop5: 5
}
}
}
}
}obj.prop1 &&
obj.prop1.prop2 &&
obj.prop1.prop2 &&
obj.prop1.prop2.prop3 &&
obj.prop1.prop2.prop3.prop4 &&
console.log(obj.prop1.prop2.prop3.prop4.prop5);
複製代碼
幸運的是,上面的代碼在咱們想要訪問的每一個級別中都定義了每一個屬性。可是,若是在任何級別的對象中都有 undefined
或 null
的嵌套對象,若是不進行檢查,那麼的程序將會崩潰。這意味着咱們必須檢查每一個級別,以確保當它遇到 undefined
或 null
對象時不會崩潰。
使用可選鏈運算符,只須要使用 ?.
來訪問嵌套對象。並且若是碰到的是 undefined
或 null
屬性,那麼它只會返回 undefined
。經過可選鏈,能夠把上面的代碼改成:
const obj = {
prop1: {
prop2: {
prop3: {
prop4: {
prop5: 5
}
}
}
}
}console.log(obj?.prop1?.prop2?.prop3?.prop4?.prop5);
複製代碼
當咱們的程序執行到 undefined
或 null
屬性時,不會崩潰,而只是返回 undefined
。不幸的是,這還沒有在任何瀏覽器中實現,因此最新版本的 Babel 來使用此功能。
來自 undefined
或 null
值的另外一個問題是,若是咱們想要的變量爲 undefined
或 null
則必須給變量設置默認值。例如:
const y = x || 500;
複製代碼
當使用 ||
運算符將 x
設置爲 y
時,若是 x
被定義爲 undefined
,咱們必須設置一個默認值。運算符 ||
的問題在於,全部相似於 0,false
或空字符串之類的值都將被咱們不想要的默認值覆蓋。
爲了解決這個問題,有人提議建立一個「nullish」合併運算符,用 ??
表示。有了它,咱們僅在第一項爲 null
或 undefined
時設置默認值。使用無效的合併運算符,以上表達式將變爲:
const y = x ?? 500;
複製代碼
例若有如下代碼:
const x = null;
const y = x ?? 500;
console.log(y); // 500const n = 0
const m = n ?? 9000;
console.log(m) // 0
複製代碼
y
將被分配的值爲 500,由於 x
的值爲 null
。可是,因爲 n
不爲 null
或 unfined
,所以 m
被賦予值爲 0
。若是咱們使用 ||
而不是 ??
,那麼因爲 0 爲假,所以將爲 m
賦值 9000。
不幸的是,此功能還沒有在任何瀏覽器或 Node.js 中實現,咱們必須使用最新版本的 Babel 才能使用此功能。
咱們能夠用 BigInt 對象表示大於 的整數。能夠經過常規操做(例如算術運算符)進行加、減、乘、除、餘數和冪等運算。它能夠由數字和十六進制或二進制字符串構造。此外它還支持 AND、OR、NOT 和 XOR 之類的按位運算。惟一無效的位運算是零填充右移運算符(
>>>
)。
一樣,一元運算符 +
也不支持 Numbers 和 BitInts 之間的加法運輸。僅當全部操做數均爲 BigInts
時才執行這些操做。在 JavaScript 中 BigInt
與普通數字不一樣。它與普通數字的區別在於,數字的末尾帶有一個 n
。
咱們可使用 BigInt 工廠函數定義 BigInt。它有一個參數,該參數能夠是整數或表明十進制整數、十六進制字或二進制的字符串。 BigInt 不能與內置 Math 對象一塊兒使用。另外在數字與 BigInt 之間進行轉換時必須當心,由於在將 BigInt 轉換爲數字時,BigInt 的精度可能會丟失,反之亦然。
要定義 BigInt,若是要傳遞的參數是整數,能夠像下面的碼同樣:
const bigInt = BigInt(1);
console.log(bigInt);
複製代碼
當咱們運行到 console.log
語句時,它將輸出 1n
。若是想將字符串傳遞給工廠函數,咱們能夠這樣寫:
const bigInt = BigInt('2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222');
console.log(bigInt);
複製代碼
也能夠經過使用以 0x
開頭的字符串將十六進制數字字符串傳遞給工廠函數:
const bigHex = BigInt("0x1fffffffffffff111111111");
console.log(bigHex);
複製代碼
當咱們在 bigHex
上運行 console.log
時,上面的代碼將輸出爲 618970019642690073311383825n
。
能夠傳入一個以 0b
開頭的二進制字符串來獲取 BigInt:
const bigBin = BigInt("0b111111111111111000000000011111111111111111111111");
console.log(bigBin);
複製代碼
當咱們在上面運行 console.log
時,上面的代碼獲得的結果是 281466395164671n
。若是要建立的 BigInt 超出數字類型能夠接受的範圍,則傳遞字符串會很方便。
還可使用 BigInt 字面量去定義 BigInt 類型。方法在整數的末尾附加一個 n
字符。例如能夠這樣寫:
const bigInt = 22222222222222222222222222222222n;
console.log(bigInt);
複製代碼
而後咱們將 22222222222222222222222222222222222n
做爲 bigInt
進行了輸出。能夠像使用數字同樣對 BigInts 進行算術運算,例如 +
、-
、/
、*
、%
等。若是咱們要使用 BigInts 進行這些操做,則全部操做數都必須都是 BigInts。可是若是咱們獲得了帶小數點的結果,則小數點之後的部分將被截斷。 BigInt 是一個大整數,不能存儲小數。例如在下面的例子中:
const expected = 8n / 2n;
console.log(expected) // 4n
const rounded = 9n / 2n;
console.log(rounded) // 4n
複製代碼
咱們獲得 expected
和 rounded
的值都是 4n
。這是由於小數部分已從 BigInt 中刪除。
比較運算符能夠應用於 BigInts。操做數能夠是 BigInt 或數字。例如能夠將 1n
與 1
進行比較:
1n === 1
複製代碼
上面的代碼將評估爲 false
,由於 BigInt 和數字不是同一類型。可是,當咱們用雙等號替換三等號時,以下面的代碼所示:
1n == 1
複製代碼
上面的語句被評估爲 true
,由於僅比較了該值。請注意,在兩個示例中,咱們都將 BigInt 操做數與數字操做數混合在一塊兒。BigInts 和數字也能夠與其餘運算符一塊兒進行比較,例如如下示例:
1n < 9
// true9n > 1
// true9 > 9n
// false9n > 9
// false9n >= 9
// true
複製代碼
一樣,它們能夠混合在一塊兒造成一個數組並進行排序。例如:
const mixedNums = [5n, 6, -120n, 12, 24, 0, 0n];
mixedNums.sort();
console.log(mixedNums)
複製代碼
如今,此功能可在最新版本的 Chrome 和 Node.js中使用。
咱們可使用 #
號來表示私有類變量。這樣就沒必要用閉包來隱藏咱們不想暴露給外界的私有變量。爲了解決對象中 null
和 undefined
值的問題,咱們提供了可選鏈運算符來訪問屬性,而無需檢查每一個級別多是 null
仍是 undefined
。使用無效的合併運算符,咱們只能爲變量爲 null
或 undefined
的狀況設置默認值。使用 BigInt 對象,咱們能夠用 JavaScript 表示超出常規數字安全範圍的大數字,並對其執行標準操做,只是小數部分將從結果中省略。