Upcoming new JavaScript features You should know if you use JavaScript everyday

Nov 4, 2019 · 5 min read

Since ECMAScript2015 (also called ES6) was released, JavaScript has changed and improved widely. This is excellent news for all of the JavaScript developers. Furthermore, a new ECMAScript version has released every year. You likely didn’t notice what features were added in the latest ECMAScript, which was released in June 2019. I will briefly show you the new features added in the latest version and talk about the new features for the future version.

The features that I will show you are NOT yet decided to be in the next version. All of what I will talk about in this post are currently in stage 3. Check out this repo if you want to get more details.

EDIT (Dec, 2019) — Stage 4

Features in ECMAScript2019 (ES10)

1. Array.prototype.flat

const array = [1, 2, [3, 4]];
array.flat(); // [1, 2, 3, 4];

This is very useful, especially when you want to flatten your nested array. If the depth of your array is deeper than one depth, calling flat once can’t entirely flatten your array. flat takes a parameter for depth, which refers to how many depths you want it to go into to flatten the array.

// Crazy example
const crazyArray = [1, 2, [3, 4], [[5], [6, [7,8]]]];
// The parameter must be the number type

The deeper you want to search the array, the more computing time will be required to flatten it. Note that IEs and Edge do not support this feature.

2. Array.prototype.flatMap

const arr = ["it's Sunny in", "", "California"];arr.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

The difference between flat and flatMap is that you can put a custom function in flatMap to manipulate each value. Additionally, unlike flat, flatMap flattens one depth array, only. The return value should be an array type. This would be very useful when you should do something before flattening the array.

There were more features added to ES10. Click here if you want to know more about them.

New Features In Stage 3

Numeric Separators

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 }
setTimeout(() => console.log(outputPlusValue(100), 1000);

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

Nullish Coalescing for JavaScript

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

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

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



JavaScript in Plain English

Learn the web's most important programming language.


Written by


Front End Web Developer in S.Korea. Interested in writing about Programmings. All of the posts could be written in English and Korean, which is my mother tongue

JavaScript in Plain English

Learn the web's most important programming language.
