Skip to main content

New JavaScript Features in ES6 ~ ES12

This article includes the most commonly used features released from ES6 to ES12.

To use those features in front end, you will need to use the babel to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

ES6 / ES2015

1. class

class Man {
constructor(name) {
this.name = name;
}
console() {
console.log(this.name);
}
}
const man = new Man('Hao');
man.console(); // Hao

2. ES Module

// export function in module A
export const sub = (a, b) => a + b;
// import function in module B
import { sub } from './A';
console.log(sub(1, 2)); // 3

3. Arrow functions

const func = (a, b) => a + b;
func(1, 2); // 3

4. Default parameters

function foo(age = 25) { 
console.log(age); // 25
}

5. Template strings

const name = 'Hao';
const str = `Your name is ${name}`;
console.log(str); // Your name is Hao

6. Destructuring assignment

let a = 1, b= 2;
[a, b] = [b, a]; // a 2 b 1

7. Spread operator

let a = [...'hello world']; // ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]

8. Object property value shorthand

const name = 'Hao',
const obj = { name };
console.log(obj); // { name: 'Hao' }

9. Promise

Promise.resolve().then(() => { console.log(2); });
console.log(1);
// print 1 ,then 2

10. let & const

let name = 'Hao'
const arr = [];

ES7 / ES2016

1. Array.prototype.includes()

[1].includes(1); // true

2. Exponentiation operator

console.log(2 ** 10); // 1024
console.log(3 ** 4); // 81
console.log(2 ** 3 ** 2); // 512

ES8 / ES2017

1. async/await

async getData(){
const res = await api.getTableData(); // await asynchronous task
// do something
}

2. Object.values()

Object.values({a: 1, b: 2, c: 3}); // [1, 2, 3]

3. Object.entries()

Object.entries({a: 1, b: 2, c: 3}); // [["a", 1], ["b", 2], ["c", 3]]

4. String padding

// padStart
'hello'.padStart(10); // " hello"
// padEnd
'hello'.padEnd(10) "hello "

5. Trailing commas in function parameters

function getMessage(str,str2,){
console.log(`${str} ${str2}`) ;
}

getMessage("hello","frank") // hello frank

ES9 / ES2018

1. Asynchronous Iteration

for await of loop support asynchronous iteration

async function process(array) {
for await (let i of array) {
// doSomething(i);
}
}

2. Promise.finally()

Promise.resolve().then().catch(e => e).finally();

3. Rest/Spread Operator

const values = [1, 2, 3, 5, 6];
console.log( Math.max(...values) ); // 6

4. Capturing groups in regular expression

Demo

const regexp = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;

console.log('2020-04-04'.match(regexp)); // {year: "1995", month: "12", day: "13"}

ES10 / ES2019

1. Array.flat() and Array.flatMap()

flat()

[1, 2, [3, 4]].flat(Infinity); // [1, 2, 3, 4]

flatMap()

[1, 2, 3, 4].flatMap(a => [a**2]); // [1, 4, 9, 16]

2. String.trimStart() and String.trimEnd()

trimStart() removes whitespace from the beginning of a string

const greeting = '   Hello world!   ';

console.log(greeting.trimStart());
// expected output: "Hello world! ";

trimEnd() removes whitespace from the end of a string

const greeting = '   Hello world!   ';

console.log(greeting.trimEnd());
// expected output: " Hello world!";

3. String.prototype.matchAll

matchAll() method returns an iterator of all results matching a string against a regular expression, including capturing groups.

const regexp = /t(e)(st(\d?))/g;
const str = 'test1 test2';

const array = [...str.matchAll(regexp)];

console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]

console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]

4. Object.fromEntries()

Object.fromEntries() method transforms a list of key-value pairs into an object.

Converting a Map to an Object

const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
console.log(Object.fromEntries(map)); // { foo: "bar", baz: 42 }

Converting an Array to an Object

const arr= [ ['foo', 'bar'], ['baz', 42] ];
console.log(Object.fromEntries(arr)); // { foo: "bar", baz: 42 }

5. Optional catch binding

Error parameter is required in try...catch before ES10

try {
console.log('Foobar')
} catch(err) {
console.error('Bar')
}

Error parameter is optional in ES10

try {
console.log('Foobar')
} catch {
console.error('Bar')
}

ES11 / ES2020

1. Nullish coalescing Operator

Nullish coalescing Operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand

let user = {
u1: 0,
u2: false,
u3: null,
u4: undefined,
u5: '',
}
let u1 = user.u1 ?? 'user1' // 0
let u2 = user.u2 ?? 'user2' // false
let u3 = user.u3 ?? 'user3' // user3
let u4 = user.u4 ?? 'user4' // user4
let u5 = user.u5 ?? 'user5' // ''

2. Optional chaining

The Optional chaining (?.) operator functions similarly to the . chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined.

let user = {}
let u1 = user.children.name // TypeError: Cannot read property 'name' of undefined
let u1 = user.children?.name // undefined

3. Promise.allSettled

The Promise.allSettled() method returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

Promise.allSettled(promises).then(results => {
results.forEach(result => {
console.log(result);
});
});

// expected output:
// "{ status: "fulfilled", value: 3 }"
// "{ status: "rejected", reason: "foo" }"

4. import()

Before ES11

if (Math.random()) {
import 'foo'; // SyntaxError
}

// You can’t even nest `import` and `export`
// inside a simple block:
{
import 'foo'; // SyntaxError
}

You can import module on demand and using [template strings]()

if (condition) {
const dynamicModule = import('./module');
}

let moduleName = 'foo';

import(`./modules/${moduleName}.js`);

5. globalThis

globalThis is used to solve the problem that the names of global objects are not uniform in different environments such as browsers and Node.js, and it is troublesome to obtain global objects:

// how we do it before globalThis exist
const getGlobal = function () {
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};

ES12 / ES2021

1. replaceAll

The replaceAll() method returns a new string with all matches of a pattern replaced by a replacement.

const str = 'hello world';
str.replaceAll('l', ''); // "heo word"

const regex = /l/ig;
str.replaceAll(regex, 'p'); // heppo worpd

2. Promise.any

Promise.any() takes an iterable of Promise objects and, as soon as one of the promises in the iterable fulfills, returns a single promise that resolves with the value from that promise

const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));

const promises = [promise1, promise2, promise3];

Promise.any(promises).then((value) => console.log(value));

// expected output: "quick"

3. Logical Assignment Operator

Logical assignment operator combines the logical operations(&&, || or ??) with assignment.

a ||= b
// equals to
a = a || (a = b)

a &&= b
// equals to
a = a && (a = b)

a ??= b
// equals to
a = a ?? (a = b)

Examples

let x = 1;
let y = 2;
x &&= y;
console.log(x); // 2
let x = 1;
let y = 2;
x ||= y;
console.log(x); // 1
let x;
let y = 2;
x ??= y;
console.log(x); // 2

4. Underscores as Numeric Separator

const billion = 1_000_000_000;
console.log(billion); // 1000000000

1_000_000_000 === 1000000000; // true