Categories
程式開發

JavaScript ES2021最值得期待的新特性解析


每年,JavaScript 的更新都會添加新特性。今年發布的是ES2020 或稱ES11,預計ES2021 或稱ES12 將於2021 年中發布。添加到JavaScript 的新特性都會經歷四個階段。在本文中,我將討論已經進入第四階段且已添加到谷歌Chrome V8 引擎中的新特性。

討論的新特性列表

  • String.prototype.replaceAll
  • 承諾
  • 邏輯運算符和賦值表達式
  • 數值分隔符
  • 國際列表格式
  • Intl.DateTimeFormat 的dateStyle 和timeStyle 選項

String.prototype.replaceAll

在JavaScript 中,replace() 方法僅替換字符串中一個模式的第一個實例。如果我們要替換字符串中某個模式的所有匹配項,則唯一的方法是使用全局正則表達式。

提案方法replaceAll() 返回一個新字符串,其中模式的所有匹配都會被替代項替換。模式可以是字符串或正則表達式,而替換項可以是字符串或針對每次匹配執行的函數。

let str="I use linux, I love linux"
str = str.replaceAll('linux', 'windows');

console.log(str)

/**** Output ****/
// I use windows, I love windows

承諾

ES2021 將引入Promise.any() 方法,只要這個方法命中了Promise 列表/ 數組中的第一個已解析的Promise,就會短路並返回一個值(如示例1a 中所述)。如果所有的promise 都被拒絕,那麼它將拋出一個匯總錯誤消息(如示例1b 所示)。

它與Promise.race() 不同,因為一旦給定的Promise 之一被解析或拒絕,Promise.any() 方法就會短路。

示例1a:即使一個Promise 在一個已解析的Promise 之前被拒絕,Promise.any() 仍將返回第一個已解析的Promise。

Promise.any([
  new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),
  new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),
  new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))

/**** Output ****/
// Result: Second

示例1b:當所有的Promise 都被拒絕時,將拋出AggregateError。

Promise.any([
  new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),
  new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),
  new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))

/**** Output ****/
// Result: Second

邏輯運算符和賦值表達式

在JavaScript 中有許多賦值運算符和邏輯運算符,如以下基本示例:

// Assignment Operator Example
let num = 5
num+=10
console.log(num) // 15
// Logical Operator Example
let num1 = 6
let num2 = 3
console.log(num1 === 6 && num2 === 2) // false
console.log(num1 === 6 || num2 === 2) // true

新的提案讓我們將能把邏輯運算符和賦值運算符結合起來。以下是&&、||和?? 運算符的一些示例:

帶有&& 運算符的邏輯賦值運算符

僅當LHS 值為真時,才將RHS 變量值賦給LHS 變量。

// Logical Assignment Operator with && operator
let num1 = 5
let num2 = 10
num1 &&= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 && (num1 = num2)
// 2. if (num1) num1 = num2

帶有||的運算符邏輯賦值運算符

僅當LHS 值為假時,才將RHS 變量值賦給LHS 變量。

// Logical Assignment Operator with || operator
let num1
let num2 = 10
num1 ||= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 || (num1 = num2)
// 2. if (!num1) num1 = num2

帶有?? 運算符的邏輯賦值運算符

ES2020 引入了空值合併運算符,其也可以與賦值運算符結合使用。僅當LHS 為undefined 或僅為null 時,才將RHS 變量值賦給LHS 變量。

// Logical Assignment Operator with ?? operator
let num1
let num2 = 10
num1 ??= num2
console.log(num1) // 10
num1 = false
num1 ??= num2
console.log(num1) // false
// Line 5 can also be written as following ways
// num1 ?? (num1 = num2)

數值分隔符

新引入的數值分隔符使用_(下劃線)字符,在數值組之間提供分隔,使數值讀起來更容易。例如:

let number = 100_000 
console.log(number)
/**** Output ****/
// 100000

國際列表格式

ListFormat 對象帶有兩個參數,它們都是可選的。第一個參數是語言(語言環境),第二個參數是具有兩個屬性(樣式和類型)的選項對象。

new Intl.ListFormat([locales[, options]])

Intl.ListFormat 有一個稱為format() 的方法,該方法接收一個數組作為一個參數,並以特定於語言環境的方式對其進行格式化。

下面給出了一些示例,這些示例結合了不同的語言環境和選項。

const arr = ['Pen', 'Pencil', 'Paper']
let obj = new Intl.ListFormat('en', { style: 'short', type: 'conjunction' })
console.log(obj.format(arr)) 
/**** Output ****/
// Pen, Pencil, & Paper

obj = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' })
console.log(obj.format(arr)) 
/**** Output ****/
// Pen, Pencil, and Paper

obj = new Intl.ListFormat('en', { style: 'narrow', type: 'conjunction' })
console.log(obj.format(arr)) 
/**** Output ****/
// Pen, Pencil, Paper

// Passing in Italy language tag
obj = new Intl.ListFormat('it', { style: 'short', type: 'conjunction' })
console.log(obj.format(arr)) 
/**** Output ****/
// Pen, Pencil e Paper

// Passing in German language tag
obj = new Intl.ListFormat('de', { style: 'long', type: 'conjunction' })
console.log(obj.format(arr)) 
/**** Output ****/
// Pen, Pencil und Paper

dateStyle 和timeStyle 選項

Intl.DateTimeFormat 對像是用來啟用語言敏感的日期和時間格式的對象構造器。新提案的dateStyle 和timeStyle 選項可用於請求給定長度的,特定於語言環境的日期和時間。

下面是不同的選項和語言(區域設置)的一些示例:

// Time only with short format
let o = new Intl.DateTimeFormat('en' , { timeStyle: 'short' })
console.log(o.format(Date.now()))
// 11:27 PM

// Time only with medium format
o = new Intl.DateTimeFormat('en' , { timeStyle: 'medium'})
console.log(o.format(Date.now()))
// 11:27:57 PM

// Time only with long format
o = new Intl.DateTimeFormat('en' , { timeStyle: 'long' })
console.log(o.format(Date.now()))
// 11:27:57 PM GMT+11

// Date only with short format
o = new Intl.DateTimeFormat('en' , { dateStyle: 'short'})
console.log(o.format(Date.now()))
// 10/6/20

// Date only with medium format
o = new Intl.DateTimeFormat('en' , { dateStyle: 'medium'})
console.log(o.format(Date.now()))
// Oct 6, 2020

// Date only with long format
o = new Intl.DateTimeFormat('en' , { dateStyle: 'long'})
console.log(o.format(Date.now()))
// October 6, 2020

dateStyle 和timeStyle 選項與不同的語言標記一起使用,如下例所示:

let abc
// English language
abc = new Intl.DateTimeFormat('en' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// October 6, 2020 at 11:40 PM

// Italian language
abc = new Intl.DateTimeFormat('it' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// 6 ottobre 2020 23:40

// German language
abc = new Intl.DateTimeFormat('de' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// 6. Oktober 2020 um 23:40

小結

作為開發人員,跟緊語言的新特性是很重要的。如果你錯過了ES2020 的特性更新,建議你閱讀這篇文章:

《ECMAScript 2020 的新功能》

英文原文鏈接:

https://codeburst.io/exciting-features-of-javascript-es2021-es12-1de8adf6550b