What's New in JavaScript for 2019
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.
Current ES2019 Candidates
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 = 9100000000000001n;
// 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" ]
More Proposed ES2019 Candidates
Here’s a list of additional Stage 3 candidates at the time of this writing.
- Standardized
globalThis
object - Dynamic
import()
- Legacy RegExp features
- import.meta
- String
matchAll()
Object.fromEntries()
- Well-formed
JSON.stringify
- Standardized Hashbang for command-line interface (CLI) applications
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.
- Learn JavaScript in 2019!
- The History (and Future) of Asynchronous JavaScript
- Build a Secure Node.js Application with JavaScript Async Await Using Hapi
- Use TypeScript to Build a Node API with Express
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.
Okta Developer Blog Comment Policy
We welcome relevant and respectful comments. Off-topic comments may be removed.