ES2021
Ecma International approves new standards - Ecma International
On 22 June, ES2021 was officially approved as a new standard and the following five features were added. Browsers also support and all ES2021 features are available in modern browsers (Chrome/Firefox/Edge/Safari).
Numeric separator
Is 100000000 a ten million or a hundred million? It’s quite hard to read immediately. Numeric separator allows you to use underscores (_) to separate numbers, making them much more readable.
const tenMillion = 10_000_000 // 1千万
const hundredMillion = 100_000_000 // 1億
console.log(1_000n.toString()) // 1000
console.log(1_000 * 2) // 2000
console.log(`${20_000 * 2 - 24_050} euro`) // 15950 euro
separated numbers by underscores (_) are still Number type, you can use them as numbers as usual. calculate, assign, whatever.
Logical assignment operators
Three new logical assignment operator, ??=、||=、&&=, were added in ES2021. But Before we go see an example, let’s go over these three logical operators. Then assign operators are not hard to understand.
||
|| returns its right-hand side operand when its left-hand side operand is Falsy.
const animal = ''
const pet = animal || 'cat'
console.log(pet) // cat
??
?? returns its right-hand side operand when its left-hand side operand is Nullish (null or undefined).
const animal1 = undefined
const animal2 = '' // falsy but not nullish
const pet1 = animal1 ?? 'cat'
const pet2 = animal2 ?? 'dog'
console.log(pet1) // cat
console.log(pet2) // ''
&&
&& returns its right-hand side operand when its left-hand side operand is Truthy.
const adult = true
const drink = adult && 'alcohol'
console.log(drink) // alcohol
||=, ??=, &&=
So, when it’s used as an assignment operator, it assigns a value when its left-hand side meets the condition (Falsy, Truthy, or Nullish).
let myPet = null
myPet ??= 'cat'
console.log(myPet) // 'cat'
let fluTestResult = 0
fluTestResult ||= 'negative'
console.log(fluTestResult) // 'negative'
let homework = 'acceptable'
homework &&= 'mathematics'
console.log(homework) // mathematics
String.prototype.replaceAll()
replaceAll() method allows you to replace all occurrences of a substring with another string that you defined. Javascript has a similar method replace(), but it only replaces the first occurrence of the substring while ignoring the rest.
Now we can easily replace all occurrences of a given string.
const s = 'Rich mom poor mom'
const replaced = s.replace('mom', 'dad')
const replacedAll = s.replaceAll('mom', 'dad')
console.log(replaced) // Rich dad poor mom
console.log(replacedAll) // Rich dad poor dad
Promise.any()
Promise.all() which I used in the article [Javascript] forEach() doesn’t wait for async/await waits until all promises are resolved. But Promise.any() resolves if any of the supplied promises is resolved.
const p1 = new Promise((resolve) => {
setTimeout(resolve, 500, 'Lion')
})
const p2 = new Promise((resolve) => {
setTimeout(resolve, 10, 'Cheetah')
})
const p3 = new Promise((resolve) => {
setTimeout(resolve, 2000, 'Munchkin')
})
Promise.any([p1, p2, p3]).then(res => {
console.log(res) // Cheetah
})
You might think ‘Hey, but, what happens if none of the promises passed is fulfilled?’ In that case, Promise.any() throws an AggregateError, so you can catch it.
const p1 = new Promise((_, reject) => {
setTimeout(reject, 500)
})
const p2 = new Promise((_, reject) => {
setTimeout(reject, 10)
})
const p3 = new Promise((_, reject) => {
setTimeout(reject, 2000)
})
Promise.any([p1, p2, p3])
.then(res => res)
.catch(error => console.log(error.message)) // All promises were reject
WeakRef
WeakRef creates a weak reference to the object passed to it. And the value of the WeakRef variable can be accessed via the deRef method.
const obj = { name: 'Alex' }
const weakRefObj = new WeakRef(obj)
console.log(weakRefObj.deref().name) // Alex
What is a weak reference? It is a situation where a reference is made, but the original object is subject to garbage collection. And garbage collection means that the computer frees up memory space that is no longer needed.
So, in short words, you have a reference, but you don’t necessarily have the reference when you want to use it.
It may be a bit tricky to use, but it is useful when you are dealing with something like cache, where it would be helpful if it existed, but if it doesn’t, it’s still fine.
However, because of the complexity of garbage collection, TC39 proposal notes says that WeakRef should probably be avoided to use.