New ES2021 JavaScript features (now available)
Tags: javascript, news, es2021, ecmascript
Published: 2021-06-29 20:30:38

*Photo by  [James Harrison](https://unsplash.com/@jstrippa)*

☕️ _[Read this article on my blog](https://javascript-for-breakfast.com/new-es2021-javascript-features)_

In case you missed it, the new ES2021 JavaScript features have been recently approved by the [Ecma General Assembly](https://www.ecma-international.org/about-ecma/organisation/) 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](https://babeljs.io/) compiler. Babel will "translate" those new features to some JavaScript that older browsers can understand. Try it out on the Babel homepage!

## Logical Assignment Operators

[📙 Proposal](https://github.com/tc39/proposal-logical-assignment)

### 1. Logical nullish assignment (`??=`)

`x ??= y` will only assign `y` to `x` if `x` is nullish (i.e. null or undefined)

```jsx
// 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
}
```

### 2. Logical OR assignment (`||=`)

`x ||= y` : this one is similar to `??=`, except it only assigns `y` to `x` if `x` is falsy

```jsx
// 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
}
```

### 3. Logical AND assignment

`x &&= y` is the exact opposite of `x ||= y` : it assign `y` to `x` if `x` is truthy

```jsx
// 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
}
```

## Numeric separator

[📙 Proposal](https://github.com/tc39/proposal-numeric-separator)

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:

```jsx
// Before
const bigNumber = 19432482347 // => ??? hard to read

// Now
const readableBigNumber = 19_432_482_347 // here we go, much better 😇
```

## String.replaceAll

[📙 Proposal](https://github.com/tc39/proposal-string-replaceall)

`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:

```jsx
// 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:

```jsx
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:

```jsx
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](https://github.com/tc39/proposal-string-replaceall):

> 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

[📙 Proposal](https://github.com/tc39/proposal-promise-any)

`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:

```jsx
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);
});
```

## WeakRefs and Finalizers

[📙 Proposal](https://github.com/tc39/proposal-weakrefs)

Those new features come together in the same proposal in order to add the ability to:

1. create *weak references* to objects with the `WeakRef` class
2. 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](https://github.com/tc39/proposal-weakrefs).

---

That's all for today folks, have a fantastic day!

With 🧡, Yohann