Home Connect Gallery Blog

What's new in ECMAScript 2017

Jade Thornton

Two years ago, ES6 (retconned to ECMAScript 2015) provided a massive update to the existing and already powerful ECMAScript standard. Incredibly useful features like const, let, arrow functions and destructuring syntax were unleashed upon the world. Another big change was the new yearly release schedule based on proposals are ready to ship as of the TC39 meeting. The next annual release, ECMAScript 2016, wasn't much to gawk at in comparison, adding only two new features—Array.protoype.includes and the exponentiation operator—and a handful of changes to the existing standard.

The newly released ECMAScript 2017 is somewhere in between, not being a massive update, but adding a sizeable number of features and changes. Let's take a look at all the new additions in this year's release.

##Object.values and Object.entries

The first addition to ECMAScript 2017 liberates us from jQuery dependence when it comes to enumerating pairs of entries or values from objects. This adds two new methods to the Object prototype, complementing pre-existing methods like keys(). values() returns an array of all values, without the keys, while entries() returns a two dimensional array of keys and values. Let's see an example use:

const jmthornton = {
  name: 'Jade',
  writes: 'code'
};

Object.entries(jmthornton);
// [['name', 'Jade'], ['writes', 'code']]
const jmthornton = {
  name: 'Jade',
  writes: 'code'
};

Objects.values(jmthornton);
// ['Jade', 'code']

Documentation:

##String padding

This new feature is relatively small, but comes to the rescue of npm and Node itself. If you don't remember, March 2016 saw a bit of a crisis where a widely used package (even by Node and Babel) called left-pad was unpublished from npm and crippled developers everywhere. This new ECMAScript feature makes the package unneeded. You can use it to easily format string output so the string reaches the given length:

'foobaring foo'.padStart(20);       // "       foobaring foo"
'foobaring foo'.padStart(20, '#');  // "#######foobaring foo"

'foobaring foo'.padEnd(20);         // "foobaring foo       "
'foobaring foo'.padEnd(20, '#');    // "foobaring foo#######"

Documentation:

##Object.getOwnPropertyDescriptors

Copying objects manually is never fun, and comes with a lot of uncertainty, and with the rising awareness and use of functional programming, immutability is very important. The new method on the Object prototype solves this issue once and for all. Object.getOwnPropertyDescriptors takes in an Object and returns the descriptors describing the attributes of a property (like value, if it's writable, etc.) Here's an example of how it's used:

const source = {
  name: 'Jackie Smith',
  id: 555
};

const sourceClone = Object.create(
  Object.getPrototypeOf(source),
  Object.getOwnPropertyDescriptors(source)
);

const stateClone = Object.create(
  Object.getPrototypeOf(this.state),
  Object.getOwnPropertyDescriptors(this.state)
);

// make changes to stateClone

this.setState(stateClone);

Documentation:

##Trailing commas in function parameter lists and calls

This new update is purely aesthetic, allowing trailing commas in function parameter lists and calls. For a long time, we've been able to put trailing commas in objects and arrays, so it's only fitting that parameter lists join the ranks. There's no performance or big underlying changes here, but I think it's a good addition. Example for clarity:

function foo(
    paramA,
    paramB,
    paramC,
  ) {
  console.log('No more complaints from the compiler!');
}

Documentation:

##Async functions

A solution to chained callbacks, that all-too-common pattern especially prevalent with APIs, async functions are a bit of syntatic sugar, but they let you write promise-based code in a way that looks synchronous. As Jake Archibald puts it, it makes "your asynchronous code less 'clever' and more readable". Check out this excellent in-depth walk-through by Nicolás Bevacqua. Here's the gist of the syntax:

async function doTheThing(data) {
  try {
    const valA = await anAsyncFunction(data);
    const valB = await aDifferentAsyncFunction(valA);
    console.log(`valB: ${valB}`);
  } catch (err) {
    console.error(`Oh noes! ${err}`);
  }
}

And to use it with an arrow function:

const doTheThing = async (data) => {
  try {
    const valA = await anAsyncFunction(data);
    const valB = await aDifferentAsyncFunction(valA);
    console.log(`valB: ${valB}`);
  } catch (err) {
    console.error(`Oh noes! ${err}`);
  }
}

Documentation:

##Shared memory and atomics

This new addition is a little more technical than others, but definitely one of the coolest. It adds a new SharedArrayBuffer, and allows the already-existing TypedArray and DataView types to be used to allocate shared memory. The associated Atomics object allows operations to be carried out on that shared memory. The proposal states these cases for justification:

  • Support for threaded code in programs written in other languages that are translated to asm.js or plain JS or a combination of the two, notably C and C++ but also other, safe, languages.
  • Support for hand-written JS or JS+asm.js that makes use of multiprocessing facilities for select tasks, such as image processing, asset management, or game AI.

The author of the proposal, Lars T Hansen, provides a tutorial for use of shared memory, and Dr Axel Rauschmayer dives in to explain it all in depth in a long form article.

Documentation:


That's it for ECMAScript 2017! Lots of new changes, and all welcome additions to the specification. Many of these features are already supported in major browsers, and the rest are soon to follow. By now, ECMAScript 2018 is in the works and I'm excited to see what proposals make it in!