What’s new in ES2017: Async functions, improved objects and more

Share this article

What’s new in ES2017

Let’s take a look at the most important JavaScript updates that came with ES2017, and also briefly cover how this updating process actually takes place.

The Update Process

JavaScript (ECMAScript) is an ever-evolving standard implemented by many vendors across multiple platforms. ES6 (ECMAScript 2015) was a large release which took six years to finalize. A new annual release process was formulated to streamline the process and rapidly add new features.

The modestly named Technical Committee 39 (TC39) consists of parties including browser vendors who meet to push JavaScript proposals along a strict progression path:

Stage 0: strawman – An initial submission of ideas for new or improved ECMAScript features.

Stage 1: proposal – A formal proposal document championed by at least one member of TC39, which includes API examples, language semantics, algorithms, potential obstacles, polyfills and demonstrations.

Stage 2: draft – An initial version of the feature specification. Two experimental implementations of the feature are required, although one can be in a transpiler such as Babel.

Stage 3: candidate – The proposal specification is reviewed and feedback is gathered from vendors.

Stage 4: finished – The proposal is ready for inclusion in ECMAScript. A feature should only be considered a standard once it reaches this stage. However, it can take longer to ship in browsers and runtimes such as Node.js.

If ES2015 was too large, ES2016 was purposely tiny to prove the standardization process. Two new features were added:

  1. The array .includes() method which returns true or false when a value is contained in an array, and
  2. The a ** b exponentiation operator, which is identical to Math.pow(a, b).

What’s New in ES2017

The feature set for ES2017 (or ES8 in old money) is considered to be the first proper amendment to the ECMAScript specification. It delivers the following goods …

Async functions

Unlike most languages, JavaScript is asynchronous by default. Commands which can take any amount of time do not halt execution. That includes operations such as requesting a URL, reading a file, or updating a database. A callback function must be passed, which executes when the result of that operation is known.

This can lead to callback hell when a series of nested asynchronous functions must be executed in order. For example:

function doSomething() {
  doSomething1((response1) => {
    doSomething2(response1, (response2) => {
      doSomething3(response2, (response3) => {
        // etc...
      };
    });
  });
}

ES2015 (ES6) introduced Promises, which provided a cleaner way to express the same functionality. Once your functions were Promisified, they could be executed using:

function doSomething() {
  doSomething1()
  .then(doSomething2)
  .then(doSomething3)
}

ES2017 Async functions expand on Promises to make asynchronous calls even clearer:

async function doSomething() {
  const
    response1 = await doSomething1(),
    response2 = await doSomething2(response1),
    response3 = await doSomething3(response2);
}

await effectively makes each call appear as though it’s synchronous while not holding up JavaScript’s single processing thread.

Async functions are supported in all modern browsers (not IE or Opera Mini) and Node.js 7.6+. They’ll change the way you write JavaScript, and a whole article could be dedicated to callbacks, Promises and Async functions. Fortunately, we have one! Refer to Flow Control in Modern JavaScript.

Object.values()

Object.values() is a quick and more declarative way to extract an array of values from name–value pairs within an object. For example:

const myObject = {
  a: 1,
  b: 'Two',
  c: [3,3,3]
}

const values = Object.values(myObject);
// [ 1, 'Two', [3,3,3] ]

You need never write a for … of loop again! Object.values is natively supported in all modern browsers (not IE or Opera Mini) and Node.js 7.0+.

Object.entries()

Object.entries() returns an array from an object containing name–value pairs. Each value in the returned array is a sub-array containing the name (index 0) and value (index 1). For example:

const myObject = {
  a: 1,
  b: 'Two',
  c: [3,3,3]
}

const entries = Object.entries(myObject);
/*
[
  [ 'a', 1 ],
  [ 'b', 'Two' ],
  [ 'c', [3,3,3] ]
]
*/

This provides another way to iterate over the properties of an object. It can also be used to define a Map:

const map = new Map(Object.entries({
  a: 1,
  b: 2,
  c: 3
}));

Object.values is natively supported in most modern browsers (but not IE, Opera Mini and iOS Safari) and Node.js 7.0+.

Object.getOwnPropertyDescriptors()

The Object.getOwnPropertyDescriptors() method returns another object containing all property descriptors (.value, .writable, .get, .set, .configurable, .enumerable).

The properties are directly present on an object and not in the object’s prototype chain. It’s similar to Object.getOwnPropertyDescriptor(object, property) — except all properties are returned, rather than just one. For example:

const myObject = {
  prop1: 'hello',
  prop2: 'world'
};

const descriptors = Object.getOwnPropertyDescriptors(myObject);

console.log(descriptors.prop1.writable); // true
console.log(descriptors.prop2.value);    // 'world'

padStart() and padEnd() String Padding

String padding has been controversial in JavaScript. The popular left-pad library was pulled from npm after it attracted the attention of lawyers representing an instant messaging app with the same name. Unfortunately, it had been used as a dependency in thousands of projects and the internet broke. npm subsequently changed operating procedures and left-pad was un-unpublished.

Native string padding has been added to ES2017, so there’s no need to use a third-party module. .padStart() and .padEnd() add characters to the start or end of a string respectively, until they reach a desired length. Both accept a minimum length and an optional 'fill' string (space is the default) as parameters. Examples:

'abc'.padStart(5);         // '  abc'
'abc'.padStart(5,'-');     // '--abc'
'abc'.padStart(10, '123'); // '1231231abc'
'abc'.padStart(1);         // 'abc'

'abc'.padEnd(5);           // 'abc  '
'abc'.padEnd(5,'-');       // 'abc--'
'abc'.padEnd(10, '123');   // 'abc1231231'
'abc'.padEnd(1);           // 'abc'

.padStart() and .padEnd() are supported in all modern browsers (not IE) and Node.js 8.0+.

Trailing Commas are Permitted

A small ES2017 update: trailing commas no longer raise a syntax error in object definitions, array declarations, function parameter lists, and so on:

// ES2017 is happy!
const a = [1, 2, 3,];

const b = {
  a: 1,
  b: 2,
  c: 3,
};

function c(one,two,three,) {};

Trailing commas are enabled in all browsers and Node.js. However, trailing commas in function parameters are only supported in Chrome 58+ and Firefox 52+ at the time of writing.

SharedArrayBuffer and Atomics

The SharedArrayBuffer object is used to represent a fixed-length raw binary data buffer that can be shared between web workers. The Atomics object provided a predicable way to read from and write to memory locations defined by SharedArrayBuffer.

While both objects were implemented in Chrome and Firefox, it was disabled in January 2018 in response to the Spectre vulnerability.

The full ECMAScript 2017 Language Specification is available at the ECMA International website. Are you hungry for more? The new features in ES2018 have been announced!

Frequently Asked Questions (FAQs) about ES2017

What are the new features introduced in ES2017?

ES2017, also known as ECMAScript 8, introduced several new features to enhance JavaScript’s capabilities. These include Async Functions, which allow for writing promise-based asynchronous code as if it were synchronous, and Shared Memory and Atomics, which provide mechanisms for safe sharing of data between multiple web workers. Other features include Object.values/Object.entries, which return arrays with the object’s values or entries, and String padding, which allows for easier formatting of strings.

How do Async Functions work in ES2017?

Async Functions in ES2017 are a combination of promises and generators that help manage asynchronous code. When an async function is called, it returns a Promise. When the async function returns a value, the Promise gets resolved with the returned value. If the async function throws an exception, the Promise gets rejected with the thrown error. The async function can contain an await expression, which pauses the execution of the async function and waits for the passed Promise’s resolution, then resumes the function’s execution and returns the resolved value.

What are Shared Memory and Atomics in ES2017?

Shared Memory and Atomics are new features in ES2017 that allow for safe sharing of data between multiple web workers. Shared Memory is implemented through the SharedArrayBuffer object, which represents a generic, fixed-length raw binary data buffer that can be used to create views on shared memory. Atomics provide atomic operations as static methods, like addition, subtraction, and so forth, which are used in conjunction with SharedArrayBuffer.

How do Object.values and Object.entries work in ES2017?

Object.values and Object.entries are methods introduced in ES2017. Object.values returns an array of a given object’s own enumerable property values, in the same order as that provided by a for…in loop. Object.entries returns an array of a given object’s own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for…in loop.

What is String padding in ES2017?

String padding is a feature introduced in ES2017 that allows for easier formatting of strings. It includes two methods: padStart and padEnd. padStart pads the current string from the start with another string until the resulting string reaches the given length. padEnd does the same but pads from the end of the current string.

How does ES2017 improve upon ES6?

ES2017 builds upon the foundations laid by ES6 by introducing new features and enhancements that make JavaScript more powerful and easier to work with. These include Async Functions for better handling of asynchronous code, Shared Memory and Atomics for safe data sharing between web workers, and new methods like Object.values/Object.entries and String padding for easier manipulation and handling of objects and strings.

How can I start using ES2017 in my projects?

To start using ES2017 in your projects, you need to ensure that your development environment supports it. Most modern browsers and Node.js versions support ES2017. You can also use transpilers like Babel to compile your ES2017 code to ES5 or ES6, which have wider support.

Are there any potential issues or challenges with using ES2017?

While ES2017 introduces many useful features, it’s important to be aware of potential compatibility issues. Not all environments fully support ES2017, so you may need to use transpilers or polyfills to ensure your code works across all platforms. Additionally, features like Shared Memory and Atomics introduce new complexities that require careful handling to avoid potential issues.

How does ES2017 compare to later versions like ES2018 and ES2019?

Each version of ECMAScript introduces new features and enhancements. While ES2017 brought features like Async Functions and Shared Memory, later versions like ES2018 and ES2019 introduced their own unique features. For example, ES2018 introduced asynchronous iteration and Promise.finally, while ES2019 introduced Array.prototype.flatMap and Object.fromEntries. It’s important to understand the features and capabilities of each version to choose the right one for your project.

Where can I learn more about ES2017 and its features?

There are many resources available to learn more about ES2017 and its features. The official ECMAScript specification is a comprehensive resource, though it can be quite technical. Online tutorials, blogs, and courses can provide more accessible introductions to the features and how to use them. Additionally, experimenting with the features in your own projects is a great way to learn by doing.

Craig BucklerCraig Buckler
View Author

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.

ECMAScriptes2017es8learn-modernjsmodernjsmodernjs-hub
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week