到了 2025 年 JavaScript 有什麼新特性?從 ES2020 到 ES2023 一次看

到了 2025 年 JavaScript 有什麼新特性?從 ES2020 到 ES2023 一次看

身為開發人員,掌握 JavaScript 的最新動態,是讓程式碼更高效、現代且具有延展性的關鍵。

在這篇文章中,我們將一起探索 ES2020 到 ES2023 令人激動不已的 JavaScript 新特性,這在許多年前是難以想像的,這些理念不僅能啟發您,也能將開發過程帶來新的光景。

本文章目次

ES2020

Optional Chaining (?.)

Nullish Coalescing (??)

邏輯賦值操作符

BigInt

GlobalThis

matchAll()

Promise.allSettled()

Dynamic import

ES2021

Promise.any()

String.replaceAll()

WeakRef and Finalizers

Numeric separators

Private Accessors

Intl.DateTimeFormat 增加 style 選項

ES2022

正規表示式匹配索引

Top-level await

String.prototype.at()

Error cause

Object.hasOwn()

類別私有屬性

ES2023

從陣列最後搜尋

Hashbang 語法

Symbol 可作為 WeakMap 的 Key

Immutable 陣列修改方法

結論

ES2020

Optional Chaining (?.)

ES2020 中引入的 Optional Chaining 可讓您讀取位於物件屬性鏈深處的值,而無需檢查鏈中的每個屬性是否存在。

let name = person?.address?.street?.name;

Nullish Coalescing (??)

ES2020 中也引入了空值合併運算符,如果一個表達式不為 null 或 undefined,則傳回第一個結果,否則傳回後面的表達式。

const person = {};

let name = person?.name ?? 'Unknown';

邏輯賦值操作符

以下操作符在 ES2020 皆可用

let x = 10;

x &&= 5; // 如果第一個值是true,則指派第二個值。

x ||= 5; // 如果第一個值是false,則指派第二個值。

x ??= 5; // 如果第一個值是undefined或null,則指派第二個值。

BigInt

BigInt 是 ES2020 中的一種新的基本型別,用於表示任意精確度的整數,從而允許使用大整數進行精確計算。

const x = 12345678901234567890n;

const y = 98765432123456789012n;

console.log(x + y);

延伸資源,如果您想要對原生 BigInt 進行一系列數學運算,請參考 bigint-toolkit

GlobalThis

新的全域物件 globalThis 提供了一種與現代 JavaScript 環境相容的存取全域物件的方法。

這個變數將傳統瀏覽器與 Node 環境各自使用的 window, this, global 等全域 root 物件集合在一起。

下面示範了在瀏覽器中, globalThis === window

console.log(globalThis === window); // true in a browser

matchAll()

String 原型物件上有一個新新方法 matchAll() ,可傳回一個迭代器,該迭代器產生正規表示式與字串的匹配,包括捕獲群組。

const regex = /(\w)(\d)/g;

const str = 'a1b2c3';

for (const match of str.matchAll(regex)) {

console.log(match);

}

Promise.allSettled()

Promise API 上的一個新方法 allSettled() 非常實用,他會傳回一個新 Promise,當陣列中的所有子 Promises 都處理完成後(無論 resolve 或 reject),這個 Promise 就得到 resolve 狀態。

const promises = [

Promise.resolve('a'),

Promise.reject('b'),

Promise.resolve('c')

];

Promise.allSettled(promises)

.then((results) => console.log(results));

Dynamic import

JavaScript 中的動態匯入可讓您選擇非同步的匯入 JS 檔案,這就像我們長年在 Webpack 和 Babel 所做的那樣。

此功能將幫助您交付按需請求的程式碼,即程式碼分割,而無需 webpack 或其他模組捆綁器的消耗。如果您願意,也可以用 if-else 區分要載入的程式碼。

if (foo === bar) {

import('./Baz').then((Baz) => {

console.log(Baz.Baz);

});

}

ES2021

Promise.any()

任何一個 Promise 成功就返回

Promise.any([promise1, promise2]).then((x) => {

myDisplay(x);

});

如果所有的 Promise 都失敗,則 Promise 背拒絕且丟出 AggregateError,也就是找到的所有錯誤的集合。

Promise.any(promises).then((value) => {

console.log(value);

}).catch((err) => { console.log("error: " + err) });

你可以用 AggregateError.errors 取得所有 Error 物件

String.replaceAll()

replaceAll 方法會將所有符合的字串替換為傳入的替換值。pattern 參數可以是字串或正則表達式模式,而 replacement 參數則可以是字串或函式。

const message = 'hello+good+morning';

const messageWithSpace = message.replaceAll('+', ' ');

// hello good morning

WeakRef and Finalizers

WeakRef 弱引用在其他語言已經很流行,它可以幫助我們建立快到更大物件​​的映射。由於 WeakRef 變數是對物件的唯一引用,因此當瀏覽器進行垃圾收集時,JavaScript 引擎可以安全地將其從記憶體中刪除並釋放空間。

const weakRef = new WeakRef({

age: 13;

});

console.log(weakRef.deref().age)

// output: 13

WeakRef 和 Finalizers 通常會一起使用。FinalizationRegistry 方法讓你可以在物件被垃圾回收機制回收後請求執行一個回呼函式。

首先,你需要定義一個帶有回呼函式的 registry(註冊表)。接著,使用 .register 方法把你想觀察的物件註冊到這個 registry。這樣一來,當物件的記憶體被垃圾回收機制釋放時,你就會立即收到通知。

const registry = new FinalizationRegistry(value => {

console.log("Finalizer");

});

registry.register({object: "Do Something"}, "testObject");

Numeric separators

這項新功能可讓您使用下劃線作為數字文字的分隔符號。它透過視覺上分隔數字分組來提高數字的可讀性。

// A billion

const amount = 1000000000; // Previous

const amount = 1_000_000_000; // With ES2021

// Hundreds of millions

const amount = 1475938.38; // Previous

const amount = 1_475_938.38; // With ES2021

Private Accessors

Private Accessors 的運作方式與 Private Methods 非常相似,我們現在可以在 JavaScript 中定義私有的 getter 和 setter,使它們只能在類別內部或透過建立的實例存取。

class ExampleClass {

get #Greeting() {return "Hello Good Morning !"

}

get viewGreetingMsg() {

return this.#Greeting

}

}

let exampleClass = new ExampleClass();

console.log(exampleClass.viewGreetingMsg);

// Hello Good Morning !

Intl.DateTimeFormat 增加 style 選項

Intl.DateTimeFormat 可以啟用依語言調整的日期和時間格式**。**dateStyle和 timeStyle`選項允許我們請求給定長度的特定於區域設定的日期和時間。

// Time with short format let.

let time = new Intl.DateTimeFormat('en' , { timeStyle: 'short' });

console.log(time .format(Date.now())); // 09:27 PM

// Time with medium format.

let time = new Intl.DateTimeFormat('en' , { timeStyle: 'medium'});

console.log(time .format(Date.now())); //09:27:50 PM

// Time with long format.

let time = new Intl.DateTimeFormat('en' , { timeStyle: 'long' }) ;

console.log(time .format(Date.now())); // 11:27:50 PM GMT+11

ES2022

正規表示式匹配索引

JS 的 Regex 匹配功能,在某些情況下,您可能不僅需要匹配的 index,還需要每個捕獲的子字串的開始和結束索引。

透過這個新功能,您可以使用修飾符: d 來表示您想要指定符合字串的起始索引和結束索引。請參閱以下範例。

const animals = "Animals: Brown Bear, Koala, Polar Bear"

// with /d flag

const regex2 = /(Bear)/dg

console.log(...animals.matchAll(regex2))

// Output:

// [

// 'Bear',

// 'Bear',

// index: 15,

// input: "Animals: Brown Bear, Koala, Polar Bear",

// groups: undefined,

// indices: [ [15, 19], [15, 19], groups: undefined, length: 2 ]

// ] [

// 'Bear',

// 'Bear',

// index: 34,

// input: "Animals: Brown Bear, Koala, Polar Bear",

// groups: undefined,

// indices: [ [34, 38], [34, 38], groups: undefined, length: 2 ]// ]

Top-level await

儘管 async await 在 JavaScript 中已經使用了一段時間,但在 ES2022 之前,await僅在 async 範圍內可用。

在 ES2022 中,您可以在最外層的空間使用 await,並為您先前處理過的同步問題提供解決方案。例如,await會暫停模組及其父模組的渲染,直到匯入資源並確保事物得到正確協調。但這項特性導致他無法被 Polyfill 用在舊瀏覽器上。

// At top level of a JS file

const translationKeys = await import(/api/${language} );

const connection = await dbConnector();

String.prototype.at()

String 原型上的新方法 at() 傳回指定位置的字串,也可以接受負數值來取得字串末端起算的字元。

const str = 'hello';

console.log(str.at(0)); // 'h'

console.log(str.at(-1)); // 'o'

Error cause

也是非常實用的功能,Error 物件擁有新屬性 cause 允許您指定錯誤的造成原因。終於可以在 catch 裡面根據錯誤原因做不同的流程判斷了。

try {

throw new Error('Error occurred', { cause: new Error('Underlying cause') });

} catch (error) {

console.log(error.cause);

}

Object.hasOwn()

Object.hasOwn() 是 hasOwnProperty() 方法的替代方法。儘管Object.prototype.hasOwnProperty已經出現在 JavaScript 規格中相當長一段時間了,但它有一些缺點,例如可以被覆蓋而造成失效,以及無法處理 Object.create(null) 建立出來的物件

let person = {

hasOwnProperty: function() {

return false;

},

age: 35

};

console.log(Object.hasOwn(person, 'age')); // true

console.log(person.hasOwnProperty('age')); // false

類別私有屬性

現在 class 可以擁有私有屬性,私有訪法,無論是動態還是靜態。也可以用 in 判斷私有欄位是否存在物件中。

class User {

#userName;

static #role;

static #login() {

this.#userName = "Hermione Granger";

}

static isLogin(user){

return #userName in user && #login in user

}

}

ES2023

從陣列最後搜尋

findLast() 與 findLastIndex()函數將允許我們根據條件查找數組的最後一個到第一個元素。

const array = [{a: 1, b: 1}, {a: 2, b: 2}, {a: 3, b: 3}, {a: 4, b: 4}]

console.log(array.findLast(n => n)); //result -> {a: 4,b: 4 }

console.log(array.findLast(n => n.a * 5 === 20)); // result -> {a:4,b:4} as the condition is true so it returns the last element.

console.log(array.findLast(n => n.a * 5 === 21)); //result -> undefined as the condition is false so return undefined instead of {a:4,b:4}.

console.log(array.findLastIndex(n => n.a * 5 === 21)); // result -> -1 as the condition is not justified for returning the last element.

console.log(array.findLastIndex(n => n.a * 5 === 20)); // result -> 3 which is the index of the last element as the condition is true.

Hashbang 語法

此功能使我們能夠在某些 CLI 中使用 Hashbang / Shebang。類似於常用的 Bash 腳本。

#! 是腳本開頭的一個特殊指令,它告訴作業系統在執行腳本時使用哪個編譯器。

#!/usr/bin/env node

console.log(2*3);

Symbol 可作為 WeakMap 的 Key

這功能允許使用唯一的 Symbol 符號作為 key。目前 WeakMap 僅限於允許物件作為 key,之後就會方便許多。

const weak = new WeakMap();

const key = Symbol('my ref');

const someObject = { a:1 };

weak.set(key, someObject);

console.log(weak.get(key));

Immutable 陣列修改方法

Array.prototype 提供了一系列新的修改功能,但都會傳回新陣列,而不是修改原有陣列。

新引進的功能有:

Array.prototype.toReversed()

Array.prototype.toSorted(compareFn)

Array.prototype.toSpliced(start, deleteCount, ...items)

Array.prototype.with(index, value)

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* toReversed */

const reversed = numbers.toReversed();

console.log("reversed", reversed); // "reversed", [9, 8, 7, 6, 5, 4, 3, 2, 1]

console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* toSorted */

const sortedArr = numbers.toSorted();

console.log("sorted", sortedArr); // "sorted", [1, 2, 3, 4, 5, 6, 7, 8, 9]

console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* with */

const replaceWith = numbers.with(1, 100);

console.log("with", replaceWith); // "with", [1, 100, 3, 4, 5, 6, 7, 8, 9]

console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* toSpliced */

const splicedArr = numbers.toSpliced(0, 4);

console.log("toSpliced", splicedArr); // "toSpliced", [5, 6, 7, 8, 9]

console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

結論

JavaScript 的語法逐漸在進化,透過這些新穎且強大的語法,我們能夠提高程式碼的效率與可讀性,以解放產能帶來更多創造性與可能性。

除了這些特性以外,今年推出的 ES2024 (ES15) 也加入了非常多令人驚豔並期待已久的功能,請參考我們另一篇文章:

ES2024 新特性介紹,改變許多未來的開發方式 (Javascript) | 夏木樂網頁設計

ES2024 (ES15) 已在今年 (2024) 7 月正式發佈。這個版本帶來了許多令人興奮且等待已久的功能,也讓 js 朝現代化語言更前進了一步。完整的官方標準請見 ECMAScript® 2024 Language Specification。 如果您想先回顧 ES2020-2023 的改變內...

simular.co

如果您還想知道更多新的 JS 特性或技術新知,歡迎關注 夏木樂 與我們的粉絲專頁。

相关推荐

护肤app哪个好用?美容护肤app推荐-比较好用的护肤app
网彩365平台下载

护肤app哪个好用?美容护肤app推荐-比较好用的护肤app

📅 08-04 👁️ 3712
2018俄罗斯世界杯门票预订和旅游心得
日博官网365bet

2018俄罗斯世界杯门票预订和旅游心得

📅 09-20 👁️ 6417
如何用日语表达‘住手’?
网彩365平台下载

如何用日语表达‘住手’?

📅 07-19 👁️ 272