Cover image for Improvements to JavaScript in the new ES2020 standard 🎁

Improvements to JavaScript in the new ES2020 standard 🎁

koddr profile image Vic Shóstak Updated on ・5 min read

How to JavaScript (2 Part Series)

1) How to write more clear `for` loops in JavaScript and why it's important? 2) Improvements to JavaScript in the new ES2020 standard 🎁


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! 👇

📝 Table of contents

⚡ Breaking news

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

  • ECMA262 (ECMAScript® 2020 Language Specification)
  • ECMA402 (ECMAScript® 2020 Internationalization API Specification)

Congratulations on our new JavaScript! 😄

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:

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:

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

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

↑ Table of contents

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:

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:

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:

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?

// 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

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:

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:

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

js es2020

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

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 (253).

// 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

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:

const array = [
    Promise.resolve("Data release"),
    Promise.reject(new Error("Something went wrong")),

  .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.

  .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

Photo by

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


If you want more — write a comment below & follow me. Thx! 😘

How to JavaScript (2 Part Series)

1) How to write more clear `for` loops in JavaScript and why it's important? 2) Improvements to JavaScript in the new ES2020 standard 🎁

Posted on Jan 15 by:

koddr profile

Vic Shóstak


Hey! 👋 I'm founder and full stack web developer (Go, JavaScript, Docker & automation) at True web artisans. Golang lover, UX evangelist, DX philosopher & UI Dreamer with over 12+ years of experience.


markdown guide

Dynamic imports are great.. and optional chaining rocks.


Yep! It's very helpful to reduce size of bundle... and looks great 😉