New Features In Stage 3

In stage 3, there are a few interesting features suggested. I will introduce some of them to you briefly.

Numeric Separators

When you assigned a big number to a variable, weren’t you confused on how big that number is or if you wrote it right? This proposal allows you to put an underscore between numbers so you can count it easier.

1_000_000_000 // Ah, so a billion

101_475_938.38 // And this is hundreds of millions let fee = 123_00; // $123 (12300 cents, apparently)

let fee = 12_300; // $12,300 (woah, that fee!)

let amount = 12345_00; // 12,345 (1234500 cents, apparently)

let amount = 123_4500; // 123.45 (4-fixed financial)

let amount = 1_234_500; // 1,234,500 let budget = 1_000_000_000_000; // What is the value of `budget`? It's 1 trillion!

//

// Let's confirm:

console.log(budget === 10 ** 12); // true

It will be up to each developer whether to use this feature once it’s released, but one thing’s for sure, this feature would reduce your headaches for counting how big a number is!

Top-level await

Top-level await enables modules to act as big async functions: With top-level await , ECMAScript Modules (ESM) can await resources, causing other modules who import them to wait before they start evaluating their body.

The motivation of this feature was that when you import a module which has async function, the output of the async function is undefined .

// awaiting.mjs

import { process } from "./some-module.mjs";

const dynamic = import(computedModuleSpecifier);

const data = fetch(url);

export const output = process((await dynamic).default, await data);

There are two files. output could be undefined if it’s called before the Promises tasks are done.

// usage.mjs

import { output } from "./awaiting.mjs";

export function outputPlusValue(value) { return output + value } console.log(outputPlusValue(100));

setTimeout(() => console.log(outputPlusValue(100), 1000);

usage.mjs will not execute any of the statements in it until the await s in awaiting.mjs have had their Promises resolved.

Nullish Coalescing for JavaScript

This would be one of the most useful features amongst proposals in stage 3. We often wrote this kind of code.

const obj = {

name: 'James'

}; const name = obj.name || 'Jane'; // James

If obj.name is falsy, then return ‘Jane’, so undefined won’t be returned. But the problem is, an empty string( ‘’ ) is also considered falsy in this case. Then we should rewrite it again like this below.

const name = (obj.name && obj.name !== '') ? obj.name : 'Jane';

It is a pain in the neck to write the code like that every time. This proposal allows you to check null and undefined only.

Optional Chaining

This proposal goes with Nullish Coalescing for JavaScript, especially in TypeScript. TypeScript has announced that they will include Nullish Coalescing for JavaScript and this proposal in their next released version, 3.7.0.

const city = country && country.city;

// undefined if city doesn't exist

Look at the example code. To get city , which is in country object, we should check if country exists and if city exists in country .

With Optional Chaining, this code can be refactored like this.

const city = country?.city; // undefined if city doesn't exist

This feature seems very handy and useful for this situation.

import { fetch } from '../yourFetch.js'; (async () => {

const res = await fetch(); // res && res.data && res.data.cities || undefined

const cities = res?.data?.cities;

})();

Promise.any

Promise.any accepts an iterable of promises and returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an array of rejection reasons if all of the given promises are rejected.

With async - await ,

try {

const first = await Promise.any(promises);

// Any of the promises was fulfilled.

} catch (error) {

// All of the promises were rejected.

}

With Promise pattern,

Promise.any(promises).then(

(first) => {

// Any of the promises was fulfilled.

},

(error) => {

// All of the promises were rejected.

}

);

Since there were Promise all , allSettled , and race , there wasn’t any . So this feature is simple but powerful for a needed situation.

However, this proposal wasn’t tested yet, so this proposal might have a longer time to be accepted in a future version of ECMAScript.