Improvements to JavaScript in the new ES2020 standard 🎁
Tags: javascript, node, news, changelog
Published: 2020-05-31 09:22:04

## Introduction

Hi, DEV community 👋 How're you today? 

Let's talk about the modern JavaScript standard → **ES2020**. Personally, all these new features make me hope that JS will become _even more_ convenient and understandable language, than it is now.

Here we go! 👇

<a name="toc"></a>
### 📝 Table of contents

- [Breaking news](#ch-0)
- [Nullish coalescing](#ch-1)
- [Optional chaining](#ch-2)
- [Dynamic imports](#ch-3)
- [Global property `globalThis`](#ch-4)
- [Arbitrary precision integers `BigInt`](#ch-5)
- [`Promise.allSettled` method](#ch-6)

<a name="ch-0"></a>
## ⚡ Breaking news

_12 Jun 2020_, The ECMA International General Assembly approved specifications, that will be discussed in this article!

- [ECMA262](https://tc39.es/ecma262/2020/) (ECMAScript® 2020 Language Specification)
- [ECMA402](https://tc39.es/ecma402/2020/) (ECMAScript® 2020 Internationalization API Specification)

Congratulations on our new JavaScript! 😄

<a name="ch-1"></a>
## Nullish coalescing

> Proposal: https://github.com/tc39/proposal-nullish-coalescing

In JavaScript there are "false" and "true" values. Now we can say that "zero" values have been added to them as well. Such values include `null` and `undefined` values.

In JavaScript world, "false" values are:

1. empty lines
2. number `0`
3. `undefined` values
4. `null`
5. `false`
6. `NaN`

But an expression to check the value to see _if it's "zero"_, will return `true` only for `null` and `undefined`. For example:

```js
const value1 = true;
const value2 = false;
const value3 = undefined;
const value4 = null;

// Function to check values
const getValue = (value) => {
    if (value || value === false) return value;
    return true;
};

getValue(value1); // => true
getValue(value2); // => false
getValue(value3); // => true
getValue(value4); // => true
```

But ES2020 standard has enough operator `??` to test for `null` and `undefined`. You can do it, even without the conditional `if` operator! 

Just rewrite `getValue` function to:

```js
const getValue = (value) => value ?? true;
```

That's all it takes. Elegant, understandable and professional! 👍

[↑ Table of contents](#toc)

<a name="ch-2"></a>
## Optional chaining

> Proposal: https://github.com/tc39/proposal-optional-chaining

Optional chains allow to organize safe access to deeply nested properties of objects without the need to verify the existence of each of them. Let's take a look at exactly how this feature works.

For example, we have this object:

```js
const user = {
    firstName: "John",
    lastName: "Doe",
    address: {
        zip: 100001,
        city: "New York",
        street: "Long str.",
        apartments: 13,
        prop1: {
            prop2: {
                prop3: {
                    prop4: {
                        value: 42
                    }
                }
            }
        }
    }
}
```

And we have the task of getting values from `address.street` and `...prop4.value`. Today, we're dealing with it somehow:

```js
if (user && user.address) {
    console.log(user.address.street); // => Long str.
}

if (user && user.address && user.address.prop1 && user.address.prop1.prop2 && 
    user.address.prop1.prop2.prop3 && user.address.prop1.prop2.prop3.prop4) {
    console.log(user.address.prop1.prop2.prop3.prop4.value); // => 42
}
```

Huge, ugly and not understandable, right? Okay. Look at the magic, that a new **ES2020** standard allows you to do:

```js
console.log(user?.address?.street); // => Long str.
console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value); // => 42
```

Is this cool! 🔥 We no longer need massive `if...else` conditions. Less code, less bugs and bundle size. But, it's not all! What, if we're make mistake and call `unknown_var`?

```js
// Current JS standard:
console.log(user.address.prop1.unknown_var); // => error? undefined? ...?

// ES2020:
console.log(user?.address?.prop1?.unknown_var); // => undefined
```

Yep, we get a single value of a non-existent variable like `undefined`. Always.

[↑ Table of contents](#toc)

<a name="ch-3"></a>
## Dynamic imports

> Proposal: https://github.com/tc39/proposal-dynamic-import

This technology allows you to import JavaScript files **dynamically, as modules**, without any additional tools. In this case, if a module is not needed, it is not imported.

> Yes, this can be made easier by taking advantage of _lazy module loading_, for example, by using a code-splitting technology available in Webpack (and not so)... but using it means **wasting** some system resources. 🤷

Code example for current JS standard:

```js
import { share } from "./share.js"; // => always load module

const shareButton = document.querySelector(".button__share");

shareButton.addEventListener("click", share); // => do something, if clicking
```

But in ES2020, we've a standard way to **dynamically** load modules:

```js
const shareButton = document.querySelector(".button__share");

shareButton.addEventListener("click", () => {
    import("./share.js")                   // => load module, only if needed
      .then((module) => module.share())    // => do something, if clicking
      .catch((error) => console.log(err)); // => handle error
});
```

[↑ Table of contents](#toc)

![js es2020](https://dev-to-uploads.s3.amazonaws.com/i/tkvsoxp9qpt2jkkljkgw.jpg)

<a name="ch-4"></a>
## Global property `globalThis`

> Proposal: https://github.com/tc39/proposal-global

On the web, global property accessible as `window` or `self` or `this`. On Node.js as `global` or `this`. And it's not a full list!

The global property `globalThis` solve this trouble. It stores **a reference** to a global object corresponding to the environment **where** your code is executed. 

No more guessing, what to call in code!

[↑ Table of contents](#toc)

<a name="ch-5"></a>
## Arbitrary precision integers (BigInt)

> Proposal: https://github.com/tc39/proposal-bigint

A new `BigInt` data type allows you to work with numbers that are longer, than the length of numbers that you could work with in JavaScript before (2<sup>53</sup>).

```js
// Current JS standard:
let n = Number.MAX_SAFE_INTEGER; // => 9007199254740991, this is 1 less than 2^53

const a = n + 1; // => 9007199254740992, ok, checks out
const b = n + 2; // => 9007199254740992, wait, that’s the same as above!

// ES2020:
let n = BigInt(Number.MAX_SAFE_INTEGER); // => 9007199254740991

const c = n + 1n; // => 9007199254740992n
const d = n + 2n; // => 9007199254740993n, this works now!
```

A `BigInt` is created by appending `n` to the end of the integer or by calling the constructor.

[↑ Table of contents](#toc)

<a name="ch-6"></a>
## `Promise.allSettled` method

> Proposal: https://github.com/tc39/proposal-promise-allSettled

The `Promise.allSettled` method will be useful, if you need your code to be executed after you have finished all promises. 

Of course, you can use the `Promise.all()` method... but it will generate an error, if at least one promise passed to it is rejected. For example:

```js
const array = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error("Something went wrong")),
];

Promise.all(array)
  .then((data) => console.log("all resolved! values:", data))
  .catch((err) => console.log("got rejected! reason:", err)); 
  
// got rejected! reason: null
```

But with `Promise.allSettled` method, promise is successfully resolved **only** after the work of other promises has been completed. And it doesn't matter, if they have been successfully or unsuccessfully executed.

```js
Promise.allSettled(array)
  .then((res) => console.log(res))
  .catch((err) => console.log(err));

// [
//     { status: "fulfilled", value: 100 },
//     { status: "rejected", reason: null },
//     { status: "fulfilled", value: "Data release" },
//     { status: "rejected", reason: Error: Something went wrong }
// ]
```

[↑ Table of contents](#toc)

<a name=""></a>
## Photo by

[Title] Oskar Yildiz https://unsplash.com/photos/cOkpTiJMGzA
[1] Caspar Camille Rubin https://unsplash.com/photos/0qvBNep1Y04

<a name=""></a>
## P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My projects that need your help (and stars) 👇

- 🔥 [gowebly][gowebly_url]: A next-generation CLI tool for easily build amazing web applications with Go on the backend, using htmx & hyperscript and the most popular atomic/utility-first CSS frameworks on the frontend.
- ✨ [create-go-app][cgapp_url]: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
- 🏃 [yatr][yatr_url]: Yet Another Task Runner allows you to organize and automate your routine operations that you normally do in Makefile (or else) for each project.
- 📚 [gosl][gosl_url]: The Go Snippet Library provides snippets collection for working with routine operations in your Go programs with a super user-friendly API and the most efficient performance.
- 🏄‍♂️ [csv2api][csv2api_url]: The parser reads the CSV file with the raw data, filters the records, identifies fields to be changed, and sends a request to update the data to the specified endpoint of your REST API.
- 🚴 [json2csv][json2csv_url]: The parser can read given folder with JSON files, filtering and qualifying input data with intent & stop words dictionaries and save results to CSV files by given chunk size.

<!-- Footer links -->

[gowebly_url]: https://github.com/gowebly
[cgapp_url]: https://github.com/create-go-app
[yatr_url]: https://github.com/koddr/yatr
[gosl_url]: https://github.com/koddr/gosl
[csv2api_url]: https://github.com/koddr/csv2api
[json2csv_url]: https://github.com/koddr/json2csv