In this article, we’re going to review some of the latest and greatest features coming with ES2020. 🔥 🤠 Getting started We are going to test these features in a Node.js environment using Babel. Method #1: creating a project from scratch Start by creating a new project: $ mkdir es2020-tests $ yarn init Now add dependencies: @babel/cli @babel/core @babel/node @babel/preset-env $ yarn add --dev @babel/cli @babel/core @babel/node @babel/preset-env Create a `.babelrc` file: { : [ ] } "presets" "@babel/preset-env" Method #2: clone the source code repository You can also clone the following repository that includes the setup and source code of the examples in this article. GitHub $ git git@github.com:olivierloverde/es2020-examples.git $ yarn install clone 🤖 The ES2020 features Private variable in Class You can now declare a private variable in a class by using a hastag . If a private variable is called outside of its class It will throw a `. # SyntaxError { #privateVariable = helloWorld() { .info( .#privateVariable) } } myClass = MyClass() myClass.helloWorld() .info(myClass.#helloWorld) class MyClass "Hello private world" console this const new // works console // SyntaxError: Private field '#helloWorld' must be declared in an enclosing class Source on GitHub BigInt There was a limitation on largest possible integer because of how Javascript represented number internally (it is using a 64-bit floating point, see . IEE 754 maxInteger = .MAX_SAFE_INTEGER; .info(maxInteger); .info(maxInteger + ); .info(maxInteger + ); .info(maxInteger + ); .info(maxInteger + ); .info(maxInteger * ); const Number console // 9007199254740991 console 1 // 9007199254740992 console 2 // 9007199254740992 ?? console 3 // 9007199254740994 console 200 // 9007199254741192 ?? console 200 // 1801439850948198100 ?? Source on GitHub Now there is a native solution, BigInt is a built-in object that provides a way to represent whole numbers larger than 2⁵³ — 1, which is the largest number in JS number). You can create a BigInt by: creating a `BigInt` object: `const value = new BigInt(500)` appending a `n` to a number: `const value = 500n` For the moment, it cannot be used with methods in the built-in `Math` object and cannot be operated with `Number`. Bitwise operators are supported except `>>>` because all BigInts are signed. maxIntegerBigInt = BigInt(maxInteger); .info(maxIntegerBigInt); .info(maxIntegerBigInt + n); .info(maxIntegerBigInt + n); .info(maxIntegerBigInt + n); .info(maxIntegerBigInt + n); .info(maxIntegerBigInt * n); // Using BigInt const console // 9007199254740991n console 1 // 9007199254740992n console 2 // 9007199254740993n console 3 // 9007199254740994n console 200 // 9007199254741191n console 200 // 1801439850948198200n Source on GitHub Promise.allSettled() Promise.allSettled takes an array of object as argument and waits that all promises settle to return the corresponding result as an array of objects `{status, ?value, ?reason}`. Promise resolvingPromise1000ms = ( setTimeout(resolve, )); rejectingPromise2000ms = ( setTimeout(reject, )); timeCheckpoint = .now(); .allSettled([ resolvingPromise1000ms, rejectingPromise2000ms ]).then( { elapsedTimeInMS = .now() - timeCheckpoint; .info( ) .info(data) }); const new Promise ( ) => resolve, reject 1000 const new Promise ( ) => resolve, reject 2000 const Date Promise => data const Date console `Promise.allSettled resolved after ms` ${elapsedTimeInMS} console /* Promise.allSettled resolved after 2006ms // ? not sure why we have 6ms [ { status: 'fulfilled', value: undefined }, { status: 'rejected', reason: undefined } ] */ Source on GitHub Nullish Coalescing Operator When you use operator, it returns the first argument to be . However, sometimes you a default value considered as such as or . To avoid it we can use the nullish coalescing operator like below: || true false 0 "" ?? object = { : { : , : } }; .info(object.car.speed || ); .info(object.car.speed ?? ); .info( || ); .info( ?? ); .info( || ); .info( ?? ); .info( || ); .info( ?? ); .info( || ); .info( ?? ); .info([] || ); .info([] ?? ); .info({} || ); .info({} ?? ); .info( || ); .info( ?? ); .info( || ); .info( ?? ); let car speed 0 name "" console 90 // 90 console 90 // 0 console null true // true console null true // true console undefined true // true console undefined true // true console 0 true // true console 0 true // 0 console "" true // true console "" true // "" console true // [] console true // [] console true // {} console true // {} console true "hey" // true console true "hey" // true console false true // true console false true // false Source on GitHub Optional Chaining Operator Let's take the following object as an example: person = { : , : }; let name "John" age 20 Let's say we want to access a property on this object that we are not sure to have, we usually do: (person.city !== && person.city.locale !== ) { cityLocale = person.city.locale; } if undefined undefined const This ensures the program does not throw any "error cannot read property name of undefined". Now with the optional chaining operator, we can be more concise: .info(person?.city?.locale); console Source on GitHub Dynamic Import Dynamic `import()` returns a promise for the module namespace object of the requested module. Thus, we can now use the `import()` function with the `await` keyword and assign the module namespace object to a variable dynamically. print = .info(value); { print }; const ( ) => value console export Source on GitHub doPrint = (value) => { Print = ( ); Print.print(value) }; doPrint( ); const async const await import './print.js' 'Dynamic import works !' Source on GitHub String.prototype.matchAll gives an array of all matches between a string and a regexp. String.prototype.match For example: doPrint = (value) => { Print = ( ); Print.print(value) }; doPrint( ); const async const await import './print.js' 'Dynamic import works !' Source on GitHub You are now ready to use these new ES2020 features! Please leave me comment if you've liked it! 🙌 This article was originally posted on my blog olivier.codes