For the last several years, JavaScript has been evolving on a steady cadence with new language features. If you’re curious to see what’s in store for the next version of JavaScript, this post is for you!

Before we talk about the latest features, it’s important to understand how new ideas become part of the JavaScript language.

The Process for New JavaScript Language Features

In a nutshell, the language specification that drives JavaScript is called ECMAScript. The Ecma International group that reviews and adopts changes to the language specification is Technical Committee 39, or TC39. Changes to the ECMAScript specification go through a standardized process, including stages of maturity.

Stage 0: ideas

Stage 1: formal proposals

Stage 2: drafts

Stage 3: candidates

Stage 4: approved

Until a language feature reaches Stage 4, there is no guarantee it will become part of the official ECMAScript language specification. However, JavaScript engine implementations, such as V8 (used by Chrome and Node.js) and Firefox’s SpiderMonkey, may add experimental support for proposed features before reaching Stage 4, so that developers can test and provide feedback.

At the time of this writing, there are no new TC39 proposals at Stage 4. However, there are a number of Stage 3 candidates.

Disclaimer: Because these are Stage 3 candidates, the final ES2019 language specification may not include all of these proposals. In fact, some of these proposals have been under consideration for years. Also, the final implementations may look or behave differently than the current candidates.

Changes to JavaScript Classes

There are a number of proposed changes to Classes, including field declarations, private methods and fields, and static methods and fields. Here’s a sample of what these changes might look like.

class Truck extends Automobile { model = " Heavy Duty " ; // public field declaration # numberOfSeats = 5 ; // private field declaration # isCrewCab = true ; static # name = " Truck " ; // static private field declaration // static method static formattedName () { // Notice that the Truck class name is used // to access the static field instead of "this" return `This vehicle is a ${ Truck . # name } .` ; } constructor ( model , seats = 2 ) { super (); this . seats = seats ; } // Private method # getBodyType () { return this . # isCrewCab ? " Crew Cab " : " Standard Cab " ; } bodyType () { return ` ${ this . # numberOfSeats } -passenger ${ this . model } ${ this . # getBodyType () } ` ; } get seats () { return this . # numberOfSeats ; } set seats ( value ) { if ( value >= 1 && value < 7 ) { this . # numberOfSeats = value ; this . # isCrewCab = value > 3 ; } } }

Personally, I don’t like the way the hash # syntax looks for private members. I would prefer to see the JavaScript language specification adopt the private keyword for this purpose, the same as in other languages.

String trimStart() and trimEnd()

The String type has a trim() method that removes whitespace from both the beginning and the end of a string. The proposed trimStart() and trimEnd() methods would allow additional control over whitespace removal.

const one = " hello and let " ; const two = " us begin. " ; console . log ( one . trimStart () + two . trimEnd () ) // "hello and let us begin."

The interesting trivia about this language feature is that it is already implemented in a number of JavaScript engines. This is one of many cases where the browsers are helping push the language forward.

Bigger Numbers with BigInt

We may see a BigInt primitive for whole numbers larger than the current maximum value of 253. A BigInt can be declared in a few different ways.

// for reference const theBiggestIntegerToday = Number . MAX_SAFE_INTEGER ; // 9007199254740991 // use the 'n' syntax to declare a BigInt const ABiggerInteger = 9100000000000001 n ; // use the BigInt() constructor const EvenBigger = BigInt ( 9100000000000002 ); // 9100000000000002n // use the BigInt() constructor with a string const SuchBigWow = BigInt ( " 9100000000000003 " ); // 9100000000000003n

Read more about the use cases and gotchas of BigInt .

Flatten Arrays with flat() and flatMap()

If you’ve studied functional programming, you may recognize flat() and flatMap() . flat() is designed to take an array of values, where some of those values may be more arrays, and returns a new one-dimensional array.

const nestedArraysOhMy = [ " a " , [ " b " , " c " ], [ " d " , [ " e " , " f " ]]]; // .flat() takes an optional depth argument const ahhThatsBetter = nestedArraysOhMy . flat ( 2 ); console . log ( ahhThatsBetter ); // [ "a", "b", "c", "d", "e", "f" ]

flatMap() is similar to map() , but the callback can return an array, and the end result will be flattened one-dimensional array instead of nested arrays.

const scattered = [ " my favorite " , " hamburger " , " is a " , " chicken sandwich " ]; // regular map() results in nested arrays const huh = scattered . map ( chunk => chunk . split ( " " ) ); console . log ( huh ); // [ [ "my", "favorite" ], [ "hamburger" ], [ "is", "a" ], [ "chicken", "sandwich" ] ] // flatMap() concatenates the returned arrays together const better = scattered . flatMap ( chunk => chunk . split ( " " ) ); console . log ( better ); // [ "my", "favorite", "hamburger", "is", "a", "chicken", "sandwich" ]

Here’s a list of additional Stage 3 candidates at the time of this writing.

When to Expect ES2019

For the past few years, TC39 has consistently released new editions of the ECMA-262 ECMAScript Language Specification in June. It is very likely we will see the ES2019 specification released this June.

Try out ES2019 Features Today

Some of the proposed language features are already available in JavaScript engines and utilities. These new features are sometimes disabled by default but can be enabled with configuration.

Test with the latest version of Node.js

Node.js uses the Chrome V8 JavaScript engine. Some of the language candidates can be used in the latest version of Node.js because V8 already supports them (e.g. Array.prototype.flat and String.prototype.trimEnd ).

You can enable other language features using --harmony-{feature-flag} command-line options. To see what flags your version of Node.js supports, use the --v8-options option to get a list. Some of the candidates are labeled as “in progress.”

macOS / Linux

node --v8-options | grep "in progress"

Windows

node --v8-options | find "in progress"

For example, to run a Node.js application that contains a class that uses field declarations and static methods, you can use the following CLI options.

node --harmony-class-fields --harmony-static-fields index.js

Test with Babel 7.0+

Babel is a JavaScript utility that allows you to use the latest language features that may not yet be supported in all browsers and environments. As you write “modern” JavaScript, Babel translates your code into equivalent syntax compatible with older engines.

Babel supports experimental language features using plugins. Babel maintains a list of supported ECMAScript proposals in their official repository.

Learn More About JavaScript and ES Next

Want to learn more about JavaScript? Check out some of these useful resources.

If you are interested, you can read the previous editions of ECMAScript, such as ES2015, ES2016, and ES2017.

Follow us for more great content and updates from our team! You can find us on Twitter, Facebook, and LinkedIn. Questions? Hit us up in the comments below.