DEV Community

Cover image for 5 ECMAScript Proposals To Look Out For In ES2020
Roy Derks
Roy Derks

Posted on

5 ECMAScript Proposals To Look Out For In ES2020

A new year, a new ECMAScript! Last year 8 proposals have reached stage 4, and are now included in the release of ES2020. In this post, I'll discuss 5 of these new additions using code examples. But first, let's have a quick look at what the process of adding a new addition to ECMAScript looks like.

The ECMAScript Process

At the very core of the specification is TC39, the committee that evolves JavaScript, adds and reviews new proposals to ECMAScript. Proposals to the specification usually represent problems that the committee (and community) is interested in exploring solutions for. New additions have to go through five stages in which their value and feasibility are tested, before being added to ECMAScript:

  • Stage 0: Strawperson: TC39 members can propose any idea, change, or addition that hasn't been proposed before (or wasn't completely rejected).

  • Stage 1: Proposal: A proposal is created by a TC39 member, and discusses a concrete problem and solution.

  • Stage 2: Draft — The syntax (most of) and semantics of the proposal are described using the formal specification language.

  • Stage 3: Candidate — Specifications for the proposal are completed and reviewers have signed-off on these.

  • Stage 4: Finished — The proposal is ready to be included in an upcoming ECMAScript release.

In 2019 some proposals made it to stage 4, including the 5 new additions listed in the next section!

Finished Proposals

As mentioned before, a proposal is finished when it reaches stage 4. At this point the proposal is complete and the syntax and semantics match the criteria of TC39. For this post I've selected 5 of these proposals that interested me the most:

1. Optional Chaining (Github)

This is probably the proposal that got the most attention of all proposals on this list. Optional chaining helps you to get rid of writing code to validate if you're able to read values by chaining. Instead of throwing an error when you use the chaining operator . to reach a value that doesn't exist, the optional chaining operator .? will return undefined. Suppose you have a variable called post with the following form:

const post = {
 title: 'My post',
 description: 'Lorem Ipsum...',
 meta: {
  title: 'My Post'
 }
}
Enter fullscreen mode Exit fullscreen mode

If you want to get the value for the title field from meta, you can use the chaining operator . to get that value:

console.log(post.meta.title)
// My Post
Enter fullscreen mode Exit fullscreen mode

But when you're not sure if the field meta will exists, you need to add a check for that field otherwise you'll get a TypeError when running your code:

const post = {
 title: 'My post',
 description: 'Lorem Ipsum...',
}

console.log(post.meta && post.meta.title)
// undefined

console.log(post.meta.title)
// Uncaught TypeError: Cannot read property 'title' of undefined 
Enter fullscreen mode Exit fullscreen mode

With the optional chaining parameter .? you can leave out the validation for the existence of the field meta like this:

console.log(post.meta?.title)
// undefined
Enter fullscreen mode Exit fullscreen mode

🚀 Play with the code on CodePen

2. Dynamic import() (Github)

Developers that use web frameworks or libraries to write applications are probably already familiar with dynamic imports. Dynamically importing modules in your application can help you with improving the performance of your application, like React.lazy does for React applications. With the dynamic import() statement you can also use this feature in any JavaScript application, so instead of a static import:

import { getPosts } from './utils';

console.log(getPosts());
// Array of posts
Enter fullscreen mode Exit fullscreen mode

You can now dynamically import this function into your application:

import("./utils").then(utils => {
 console.log(utils.getPosts());
 // Array of posts
});
Enter fullscreen mode Exit fullscreen mode

And even destructure the getPosts function while doing so:


let posts = []

import("./utils").then(({ getPosts }) => {
 console.log(getPosts());
 // Array of posts
});
Enter fullscreen mode Exit fullscreen mode

By dynamically importing code you can reduce the time that your applications take to load, and focus on returning something to the user as fast as possible.

3. Promise.allSettled (Github)

In recent releases of ECMAScript, there have been multiple additions that improved the Promise constructor, which are Promise.all, Promise.race, and Promise.any. These methods (or also called Promise combinators) help you tying multiple Promises together, like using the Promise.all method to combine the results of multiple Promises (or in example fetch requests):

const promises = [
 Promise.resolve(1),
 Promise.resolve(2),
 Promise.resolve(3)
];

Promise.all(promises)
 .then(responses => console.log(responses)) // [1, 2, 3]
 .catch(e => console.log(e))
Enter fullscreen mode Exit fullscreen mode

As all Promises resolve, the response will be the combined results of all Promises. The downside is that when one of your Promises rejects, the results don't get returned:

const promises = [
 Promise.resolve(1),
 Promise.resolve(2),
 Promise.reject('error')
];

Promise.all(promises)
 .then(responses => console.log(responses))
 .catch(e => console.log(e)) // "error"
Enter fullscreen mode Exit fullscreen mode

Instead of returning the combined results of all Promises, only the results of the rejected Promise will be returned. The Promise.allSettled method fixes this by returning a status for all the Promises:

Promise.allSettled(promises)
 .then(responses => console.log(responses.map(response => response.status))) // ["fulfilled", "fulfilled", "rejected"]
Enter fullscreen mode Exit fullscreen mode

And also the values if the Promise resolved, or the reason for rejecting the Promise:

Promise.allSettled(promises)
 .then(responses => console.log(responses.map(response => response.value || response.reason))) // [1, 2, "error"]
Enter fullscreen mode Exit fullscreen mode

🚀 Play with the code on CodePen

4. Nullish coalescing Operator (Github)

This last addition I'd like to mention is somewhat similar to the optional chaining operator .?, as both additions help you to skip writing code for validating values. In the case of the nullish coalescing operator ??, it saves you time checking for values that are falsy null, like an empty string:

const post = {
 title: 'My post',
 description: 'Lorem Ipsum...',
 meta: {
  title: ''
 }
}

console.log(post.meta.title || 'Not found')
// Not found
Enter fullscreen mode Exit fullscreen mode

Above you can see that the value for title in meta is an empty string, which is seen as false by the || operator. However, with the nullish coalescing operator ?? the value for metaTitle will be the empty string:

console.log(post.meta.title ?? 'Not found')
// ''
Enter fullscreen mode Exit fullscreen mode

🚀 Play with the code on CodePen

5. BigInt (Github)

This last one might not be an addition that you'll use, but I'm pretty sure it will show up in technical interviews. With the BigInt primitive, the biggest Number that can be represented in JavaScript is no longer 9007199254740991. If you look at the maximum value of Number, you'll see the following:

const maxNumber = Number.MAX_SAFE_INTEGER

console.log(maxNumber) // 9007199254740991

console.log(maxNumber + 1) // 9007199254740992
console.log(maxNumber + 2) // 9007199254740992
Enter fullscreen mode Exit fullscreen mode

As 9007199254740992 is the maximum value Number can represent in JavaScript, you can't exceed this number. However, with BigInt you can get a higher value:

const maxNumber = Number.MAX_SAFE_INTEGER

const biggerNumber = BigInt(maxNumber) + 2n
console.log(biggerNumber) // 9007199254740993n
Enter fullscreen mode Exit fullscreen mode

Notice, you can't add the value 2 to the BigInt, instead, you need to add the value 2n. To display the value of the BigInt you need to use the method toString() or toLocaleString(), as the value can only be used for calculations

console.log(biggerNumber.toString()) // "9007199254740993"
Enter fullscreen mode Exit fullscreen mode

🚀 Play with the code on CodePen

What else?

In this post, I've shared my favorite new additions to the ECMAScript specification, but more have been released in ES2020. For the full list of finished (and released) proposals, you can have a look here. Missing a new addition that you like on this list? Use the comments section or Twitter to let me know!

Photo by SpaceX on Unsplash

Latest comments (1)

Collapse
 
northtree profile image
northtree

Nice introduce for these specs.

There is one typo:

the optional chaining operator .?

The operator is ?.