19
New ES2021 JavaScript features (now available)
Photo by James Harrison
In case you missed it, the new ES2021 JavaScript features have been recently approved by the Ecma General Assembly and are now already supported by recent versions of the most popular browsers, yeay 🎉
📝 Note: For older browsers support (which you should definitely care about), you will need to set up your project with the Babel compiler. Babel will "translate" those new features to some JavaScript that older browsers can understand. Try it out on the Babel homepage!
x ??= y
will only assign y
to x
if x
is nullish (i.e. null or undefined)
// Example 1: x is nullish
let x
const y = 'Chuck Norris'
// ✅ x is assigned 'Chuck Norris'
x ??= y
// Example 2: x is not nullish
let x = 1
const y = 2
// 🔴 x is not assigned 2, its value remains 1
x ??= y
// Translates to this
x ?? (x = y)
// or this
if (x === null || typeof x === 'undefined') {
x = y
}
x ||= y
: this one is similar to ??=
, except it only assigns y
to x
if x
is falsy
// Example
let x = 0
const y = 2
// ✅ x is assigned 2
x ||= y
// Translates to this
x || (x = y)
// or this
if (!x) {
x = y
}
x &&= y
is the exact opposite of x ||= y
: it assign y
to x
if x
is truthy
// Example
let x = 1
const y = 2
// ✅ x is assigned 2
x &&= y
// Translates to this
x && (x = y)
// or this
if (x) {
x = y
}
I have been waiting for this one for a long time. It simply improves readability of big numbers, without changing anything to performance nor equality:
// Before
const bigNumber = 19432482347 // => ??? hard to read
// Now
const readableBigNumber = 19_432_482_347 // here we go, much better 😇
String.prototype.replaceAll(searchValue, replaceValue)
Until now, we had String.prototype.replace
which replaced the first occurrence * of a pattern in a string. In order to replace *every occurrence, we had to use a regular expression with the global flag:
// String.prototype.replace (searchValue, replaceValue)
const str = "This is a test, I repeat, this is a test"
str.replace(/test/g, 'success')
// output: This is a success, I repeat, this is a success
There is also a trick which consists of using the split
and join
methods:
str.split('test').join('success')
// output: This is a success, I repeat, this is a success
This can now be done using the replaceAll
method:
str.replaceAll('test', 'success')
// output: This is a success, I repeat, this is a success
Just like with String.prototype.replace
, searchValue
can be a regular expression, but it has to include a global flag, otherwise it will throw an exception. As mentioned in the proposal:
This is done to avoid the inherent confusion between the lack of a global flag (which implies "do NOT replace all") and the name of the method being called (which strongly suggests "replace all").
Promise.any([promise1, promise2, promise3]).then(...).catch(...)
Promise.any
is a new promise method that takes an array of promises and resolves with the value of the first promise to successfully resolve. It will throw an AggregateError
if all the promises are rejected.
This snippet (from the proposal) checks which endpoint responds the fastest, and then logs it:
Promise.any([
fetch('https://v8.dev/').then(() => 'home'),
fetch('https://v8.dev/blog').then(() => 'blog'),
fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => {
// Any of the promises was fulfilled.
console.log(first);
// → 'home'
}).catch((error) => {
// All of the promises were rejected.
console.log(error);
});
Those new features come together in the same proposal in order to add the ability to:
- create weak references to objects with the
WeakRef
class - running user-defined finalizers after objects are garbage-collected, with the
FinalizationRegistry
class
I won't go into more details about those features as they are quite advanced, and, as the proposal states:
Their correct use takes careful thought, and they are best avoided if possible.
But if you're interested, feel free to read more in the original proposal.
That's all for today folks, have a fantastic day!
With 🧡, Yohann
19