JS學習筆記-ES2021/ES12令人期待的新功能

Eason Lin
Eason’s murmuring
8 min readNov 21, 2020

2020 即將進入最後一個月,今天偶然在 Medium 首頁看到了 ES2021 這個關鍵字,就找了一些資料並且記錄在這邊。

EMCAScript 每年都會有一些新的特性被納入規範中,由一個稱為 TC39 的委員會負責這一塊,從提出到正式納入規範會歷經 strawman,隨後是 proposal > draft > candidate > finished 四個階段,通過後就會成為在年度發布的規範中,今天會記錄已經進入第四階段,將成為 ES2021 標準的新特性。

String.prototype.replaceAll

以往我們要在字串大量取代某個文字時都必須要使用正規表達式去達成:

const str = '江南可採蓮,蓮葉何田田,魚戲蓮葉間,魚戲蓮葉東,魚戲蓮葉西,魚戲蓮葉南,魚戲蓮葉北。'
const reg = /魚戲/gi
console.log(str.replace(reg, '')) // 江南可採蓮,蓮葉何田田,蓮葉間,蓮葉東,蓮葉西,蓮葉南,蓮葉北。

使用 replaceAll 就可以這樣寫:

const str = '江南可採蓮,蓮葉何田田,魚戲蓮葉間,魚戲蓮葉東,魚戲蓮葉西,魚戲蓮葉南,魚戲蓮葉北。'console.log(str.replaceAll('魚戲', ''))

可以達成相同的效果。

Promise.any

Promise.all 可以接收一個包含 Promise 的可迭代物件並回傳一個 Promise,例如:

const p1 = new Promise((resolve) => {
setTimeout(() => {
resolve('p1 resolved value')
}, 1000)
})
const p2 = new Promise((resolve) => {
setTimeout(() => {
resolve('p2 resolved value')
}, 500)
})
const p3 = new Promise((resolve) => {
setTimeout(() => {
resolve('p3 resolved value')
}, 1800)
})
Promise.all([p1, p2, p3]).then(values=>{
console.log(values)
}) // ["p1 resolved value", "p2 resolved value", "p3 resolved value"]

Promise.any 則會在參數中的任何一個 Promise resolve 時就 resolve 它的值,例如:

Promise.any([p1, p2, p3]).then(value=>{
console.log(value)
}) // p2 resolved value

Promise.all 會在有任何一個 Promiserejectreject 它的值:

const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p1 reject')
}, 1600)
})
const p2 = new Promise((resolve) => {
setTimeout(() => {
resolve('p2 resolved value')
}, 1500)
})
const p3 = new Promise((resolve) => {
setTimeout(() => {
resolve('p3 resolved value')
}, 1800)
})
Promise.all([p1, p2, p3]).then(values=>{
console.log(values)
})
// Uncaught (in promise) p1 reject

Promise.any 則會在所有 Promisereject 時拋出一個 AggregateError

const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p1 reject')
}, 1600)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p2 reject')
}, 1500)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p3 reject')
}, 1800)
})
Promise.any([p1, p2, p3]).then(values=>{
console.log(values)
})
// Uncaught (in promise) AggregateError: All promises were rejected

Logical Assignment Operator

在開發時我們可以使用邏輯運算子 || && 以及 ES2020 時提出的 ?? (Nullish coalescing operator)去解決一些問題。

a || b 會在 a 的值為 truthy 時回傳 a,否則回傳 b,例如:

'some random texts' || null // "some random texts"
0 || null // null
'' || undefined // undefined

a && b 會在 a 的值為 falsy 時回傳 a,否則回傳 b,例如:

'some random texts' && null // null
0 && null // 0
'' && undefined // ""

a ?? b 會在 a 的值為 nullundefined 時回傳 b,否則回傳 a,當 ab 均為 nullundefined 時則回傳 b。例如:

null ?? false // false
0 ?? undefined // 0
undefined ?? null // null

而 ES2021 即將提出的 ||= &&= ??= 概念上就是類似 +=

var b = 2
b += 1
// 等同 b = b + 1
var a = null
a ||= 'some random text' // a 變成 'some random text'
// 等同 a = a || 'some random text'
var c = 'some random texts'
c &&= null // c 變成 null
// 等同 c = c && null
var d = null
d ??= false // d 變成 false
// 等同 d = d ?? false

weakref

如果一個物件不在被任何物件引用,它就會被判定為可以被回收以釋放記憶體的垃圾,例如 MDN 上的範例:

var o = { 
a: {
b: 2
}
};
var o2 = o; // o2 引用物件 o
o = 1; // 現在,物件 o 有另一個不同的引用
// 而原本在物件 o 的物件,則被物件 o2 引用
var oa = o2.a; // 現在物件 a 被 o2 及 oa 引用o2 = 'yo'; // 現在 o2 變成 'yo'
// 現在 a 僅被 oa 引用
oa = null; // 現在把 oa 變成 null
// 因為沒有任何物件與變數引用 a ,因此他可以被回收

weakref 可以讓我們拿到一個物件的弱引用,弱引用將不會阻止物件被垃圾機制回收,當其被回收時,這個弱引用就無法再獲取該物件。

let weakRef = new WeakRef({ bigObj: 'a bigObj'})

我們可以使用 weakRef.defef() 去拿到其中的物件,但是當物件被回收時,拿到的就會是 undefined

--

--