七種武器:JavaScript 新特性閃亮登場


JavaScript(或ECMA Script) 是一門不斷發展的語言,有許多關於如何前進的建議和想法。TC39(技術委員會39)是負責定義JS標准和特性的委員會,今年他們非常活躍。以下是目前處於“Stage 3階段”的一些提案摘要,這是“完成”之前的最后一個階段。這意味着這些特性將很快在瀏覽器和其他引擎中實現。事實上,其中一些現在就有了。

1. 私有字段#

Chrome 和 NodeJS 12 已支持

是的,你沒看錯。JS終於在類中支持私有字段了。不再有 this._doPrivateStuff()、定義閉包來存儲私有值或者使用WeakMap來間接實現私有屬性。

語法是這樣的:

// 私有字段必須以 '#' 開頭
// and they can't be accessed outside the class block

class Counter {
  #x = 0;

  #increment() {
    this.#x++;
  }

  onClick() {
    this.#increment();
  }

}

const c = new Counter();
c.onClick(); // 正常
c.#increment(); // 出錯

提案: https://github.com/tc39/proposal-class-fields

2. 可選鏈式調用 ?.

以往需要訪問嵌套在對象內部好幾層的屬性時,會得到臭名昭著的錯誤Cannot read property 'stop' of undefined。然后你就要改變代碼來處理屬性鏈中每一個可能的undefined對象,比如:

const stop = please && please.make && please.make.it && please.make.it.stop;

// 或者使用 'object-path' 這樣的庫
const stop = objectPath.get(please, "make.it.stop");

有了可選鏈式調用 ,你只要這樣寫就可以做同樣的事情:

const stop = please?.make?.it?.stop;

提案: https://github.com/tc39/proposal-optional-chaining

3. 空合並操作符 ??

變量的可選值可能沒有,如果沒有則使用默認值。這種情況很常見:

const duration = input.duration || 500;

使用||的問題是,它會覆蓋所有的假值,如(0''false),這些值可能是在某些情況下有效的輸入。

輸入空合並操作符,它只覆蓋undefinednull

const duration = input.duration ?? 500;

提案: https://github.com/tc39/proposal-nullish-coalescing

4. BigInt 1n

Chrome 和 NodeJS 12 已支持

JS在數學方面一直很糟糕的一個原因是,我們無法可靠地存儲大於2 ^ 53的數字,這使得處理相當大的數字非常困難。幸運的是,BigInt是解決這個特定問題的提案。

// 可以通過附加'n'到一個數字字面量來定義BitInt
const theBiggestInt = 9007199254740991n;

// 使用構造器
const alsoHuge = BigInt(9007199254740991);

// 或則字符串形式
const hugeButString = BigInt('9007199254740991');

你也可以在BigInt上使用與普通數字相同的運算符,例如 +-/*%等等。不過有一個問題,在大多數操作中,不能將 BigIntNumber混合使用。比較Number和 BigInt是可以的,但是不能把它們相加。

1n < 2 
// true

1n + 2
// 🤷‍♀️ Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

提案: https://github.com/tc39/proposal-bigint
參考閱讀:一文搞懂JavaScript 新數據類型BigInt

5. static 字段

Chrome & NodeJS 12 已支持

這個很簡單。它允許類擁有靜態字段,類似於大多數OOP語言。靜態字段可以用來代替枚舉,也可以用於私有字段。

class Colors {
  // public static 字段
  static red = '#ff0000';
  static green = '#00ff00';

  // private static 字段
  static #secretColor = '#f0f0f0';

}

font.color = Colors.red;

font.color = Colors.#secretColor; // Error

提案: https://github.com/tc39/proposal-static-class-features

6. 頂層 await

Chrome 已支持

允許您在代碼的頂層作用域使用await。這對於在瀏覽器控制台中調試異步內容(如 fetch)非常有用,而不需要在異步函數中包裝它。
using await in browser console

另一個殺手級用例是,它可以在用異步方式初始化的ES模塊的頂層使用(比如建立數據庫連接)。當這樣一個異步模塊被導入時,模塊系統將等待它解析,然后再執行依賴它的模塊。這將使處理異步初始化比目前通過返回一個初始化promise並等待它解決來得更容易。模塊將不知道它的依賴是否異步。

// db.mjs
export const connection = await createConnection();

// server.mjs
import { connection } from './db.mjs';

server.start();

在本例中,server.mjs 中不執行任何操作,直到在db.mjs中完成連接。
提案:https://github.com/tc39/proposal-top-level-await

參考閱讀:頂層 await 釋疑

7. WeakRef

  • Chrome 和 NodeJS 12 已支持*

對象的弱引用是不足以對象處於活動狀態的引用。當我們使用(constletvar)創建一個變量時,垃圾收集器(GC)將永遠不會從內存中刪除該變量,只要它的引用仍然是可訪問的。這些都是強引用。然而,弱引用引用的對象如果沒有強引用,則GC可以在任何時候刪除它。WeakRef實例有一個方法deref,它返回引用的原始對象,如果原始對象被回收,則返回undefined 。

這對於緩存廉價對象可能很有用,因為你不想將所有對象都永遠存儲在內存中。


const cache = new Map();

const setValue =  (key, obj) => {
  cache.set(key, new WeakRef(obj));
};

const getValue = (key) => {
  const ref = cache.get(key);
  if (ref) {
    return ref.deref();
  }
};

const fibonacciCached = (number) => {
  const cached = getValue(number);
  if (cached) return cached;
  const sum = calculateFibonacci(number);
  setValue(number, sum);
  return sum;
};

對於緩存遠程數據來說,這可能不是一個好主意,因為遠程數據可能會不可預測地從內存中刪除。在這種情況下,最好使用LRU之類的緩存。
提案:https://github.com/tc39/proposal-weakrefs


以上。希望你和我一樣對使用這些很酷的新功能感到興奮。要了解更多關於這些提案和其他我沒有提到的細節,請關注github上的TC39提案

原文:7 Exciting New JavaScript Features You Need to Know

交流

歡迎關注微信公眾號“1024譯站”,跟我一起關注最新技術趨勢。
微信公眾號:1024譯站


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM