ES8 (or ES2017) – What’s New in JavaScript?

Posted by: V Keerti Kotaru , on 12/13/2017, in Category JavaScript
Views: 26012
Abstract: ES8 or ES2017 is the eighth version of the JavaScript language specification created to offer new features and ways of working with JavaScript. This article talks about the new features in ES8/ES 2017.

ECMAScript/ES is a language specification created to standardize JavaScript.

ES5, the fifth version of the specification and released in 2009, enabled the language with important and powerful features. It allowed sophisticated UI applications built with JavaScript. ES6 onwards, ECMA script releases have been once a year.

Are you keeping up with new developer technologies? Advance your IT career with our Free Developer magazines covering Angular, React, .NET Core, MVC, Azure and more. Subscribe to this magazine for FREE and download all previous, current and upcoming editions.

ES6 is also called ES2015. ES7 is ES2016 and ES8 is ES2017.

TC39 proposals and Stage definitions

The Ecma TC39 committee is responsible for evolving ECMAScript. TC39 uses the following stage definitions to move a JavaScript feature to one of the ECMA Script releases.

Features/specifications in stage 4, in time for each year’s release, are included in the release.

ecma-stage-definitions

ECMAScript 2017 (ES8) New Features

Following are the new features in ES8/ES2017.

async/await

Context

JavaScript is asynchronous. Traditionally, callbacks were passed and invoked when an asynchronous operation returned with data. But in this model, callbacks invoked callbacks which invoked more callbacks that created a callback hell scenario.

Promises largely solved this problem with each asynchronous operation/function returning a promise object. A promise could be resolved successfully with data. And in case of a failure, it got rejected with error information.

Following is a Promise constructor introduced in ES6. Before this API was introduced, ES5 used promises from libraries like JQuery, Q etc.

const getData = () => {
    return new Promise( (resolve, reject) => {
        // resolve after 3 second timeout.
        setTimeout(() => resolve({ key: new Date().getTime()}), 3000 );
    });
}

The getData function creates and returns a promise object. It has two function callbacks passed in as parameters: resolve and reject. The sample we just saw invokes resolve, once it times out.

The following processData function invokes getData. It returns a promise. When the promise is resolved, processData can utilize the JSON retrieved.

In this basic sample, let’s console.log it.

function processData(){
  getData().then((data) => console.log(data));
};

Imagine processData() needs to return data with additional modifications done to it. Without async/await, which will be detailed shortly, we will have to create another Promise, modify the data and then resolve it.

Here’s how the processData function returns a new promise.

function processData() {
   return new Promise((resolve, reject) => getData()
          .then((data) => resolve( {ticks: data.key || 0})));
}

An async function simplifies this syntax. Use await keyword to assign data to a variable when a promise is resolved. A function using await (parent) needs to be marked async.

Consider the following code snippet for the syntax where the function starts with the async keyword.

async function processData() {
    // getData() function returns a promise. 
    let data = await getData();
    return { "ticks": data.key || 0 };
}

For an arrow function syntax, consider the following code snippet. Notice the use of async keyword before the parameter list.

const processData = async () => {
    let data = await getData();
    return { "ticks": data.key || 0 };
}

Let’s print the object returned from processData.

Note: Most samples in this article could be run on a browser prompt, like Google Chrome console. They are simple enough to be legible on the browser console. If you feel comfortable to write it in a separate JavaScript file, you may do so.

console.log(processData());

(Output on Google Chrome)

promise-object

As you can see, it returned a promise implicitly.

We may use the then callback to print the data returned

processData().then((data) => console.log(data));

Or use await.

(async () => console.log(await processData()))();

Because every function using await needs to be marked async, we are using a self-executing function here.

Errors in async function

An error in async function rejects the returned promise. Consider the following sample.

error-async

Notice the errorAsync function throwing an Error object. It results in an error callback (of the promise) invoked.

Browser Support

The following table depicts browser support by version (when the support started). Keep in mind, this may change with potentially more browsers supporting the feature. This information is as of 1st Oct 2017 (at the time of authoring the article).

browser-support

Editorial Note: Please use the “Links and References” section at the end of this article for the most current browser support information.

Object.entries

The API Object.keys has been available since the ES5 days (with certain improvements in ES6).

It returns all keys of an object. Complementing this API, Object.entries is added to the ECMA Script proposal to enable an object to be used with an iterator.

Object.entries returns an array of key/value pairs for a given object. Consider the following sample.

object-entries

One of the use cases for the API is that the returned entries could be iterated through by creating a map object.

map-object

Please note Object.entries returns an array for only the enumerable properties of an object.

Browser Support

Follow the link in “Links and References” section for the most current browser support information.

object-entries-browser-support

Object.values

Complimenting Object.keys and Object.entries, the Object.values also returns enumerable values of a JavaScript object. It allows an object to be used with an iterator.

object-values

Browser Support

Follow the link in “Links and References” section for the most current browser support information.

object-values-browser-support

String.prototype.padStart

This is a new string handling function in ES2017 to pad the given string at the beginning. Consider the following sample:

string-padstart

The resultant string will be of the length specified.

padstart-length

In the sample we saw, the string is padded with a space (U+0020). This is the default character. We can pass an additional parameter with the string to be padded at the start.

padstart-default

Browser Support

Follow the link in “Links and References” section for most current browser support information.

padstart-browser-support

String.prototype.padEnd

This is another new String handling function to pad a given string at the end. Consider the following sample:

string-padend

The resultant string will be of the length specified.

padend-length

In the sample above, the string is padded with a space (U+0020), which is the default character. We can also pass an additional parameter with the string to be padded at the end.

padend-default

Browser Support

padend-browser-support

Trailing commas in function parameters

You can now allow a syntax to end the parameter list of a function with a comma (followed by no parameter). Consider the following,

const func = (p1,
  p2,
  ) => `parameter1: ${p1}. parameter2: ${p2}`;

This is to help semantics with source control products. Consider the following definition:

If a function parameter p3 is added by a team member, adding comma after p2 will annotate this line too that is changed by a team member. Allowing trailing comma will let the new line be added without touching the line with p2.

trailing-commas

This doesn’t affect length on function object.

function-length

getOwnPropertyDescriptors

This method returns property descriptors of a given object. Descriptors include the following information about each property on an object,

  • Value – value associated with the property.
  • Writable – If true, attribute can be read from and written to. If not, will be a read only property.
  • Get – getter function for the property
  • Set – setter function for the property.
  • Configurable – if true, property descriptor may be modified and property is allowed to be deleted.
  • Enumerable – If true, property shows up while enumerating the object.

Refer to the following snippet. It shows a descriptor on a sampleKey of an object.

get-own-property

We often need to use immutable JavaScript objects. Many frameworks (like Redux for application state) require objects to be immutable. To ensure immutability, we often clone an object. There was no clean way to clone an object in JavaScript.

Object.assign is a common API used to clone an object. Consider the following code:

object-assign

Notice key1 and key2 are defined with a descriptor object. It allows us to provide additional descriptor metadata. For example, we can’t change the values of key1 and key2 as it’s not writable and no setter defined.

Review the code snippet below.

object-descriptor

Using Object.assign for the above example will clone object1 but the descriptors’ metadata is lost.

lost-metadata

With the use of getOwnPropertyDescriptors, cloning can be done along with the descriptors.

Consider the following snippet:

retained-descriptor

Finally, compare descriptors information among the three objects object1, object2 and object3. Notice object1 and object3 have similar descriptors considering cloning included descriptors.

compare-descriptors

Browser Support

object-descriptor-browser-support

SharedArrayBuffer

It enables creation of a shared location to use between agents. While we create web workers, data can be shared with postMessage call. Before SharedArrayBuffer, there is no common memory between threads.

SharedArrayBuffer enables using a common memory location between threads. Here’s a code snippet which creates a worker and posts a message.

var work1 = new Worker('workerFile.js');
var msg = {"key1": "sample value"};
work1.postMessage(msg);

Here’s the worker snippet:

onmessage = (event) => {
     console.log(event.data);
};

Note that changing the message object doesn’t reflect in the worker file. We could use SharedArrayBuffer to have a common location that gets updated in the worker when modified in the main thread.

Consider the following piece of code which creates a worker, and creates SharedArrayBuffer with Int32Array (view). It will first post the data to the worker (thread). The worker is expected to print data in a loop. After couple of seconds, the main thread will update the data.

// Create Worker
var work1 = new Worker('workerFile.js');

// Create SharedArrayBuffer
var sab = new SharedArrayBuffer(4);
var ia = new Int32Array(sab);

// set value
ia[0] = 10;

// post data to the worker 
work1.postMessage(ia);

// after 2 seconds update the posted object.
setTimeout( () => ia[0]=20, 3000);

Notice the change made in the main thread, is reflected in the worker.

worker-change

Review the code in the worker that prints data in a loop.

console.log("--- Web Worker Ready! ---");

let state
onmessage = (event) => {
    state = event.data;
    iterateAndPrint(); // once data is received, invoke the function to print
};

// print data in global variable. Iteratively call same function every second.
const iterateAndPrint = () => {
    console.log(state);
    setTimeout(() => iterate10Times(), 1000);    
};

Browser Support

shared-array-browser-support

Atomics

One of the problems with SharedArrayBuffer is that it’s difficult to say when the data will be synchronized among threads or agents. Yes, it will eventually get synchronized but the speed of synchronization is system dependent, i.e. based on availability of resources.

Atomics helps solve this problem about predictability. Atomics provides many static functions that enables a unit work performed. An operation like store will be predictable and won’t return, till finished.

The following code snippet saves and reads using Atomics’ static functions.

// store a value 10 at array index 0 for the variable (SharedArrayBuffer) ia 
 Atomics.store(ia,0,10);
 
 // return value at zeroth position in the variable ia.
 Atomics.load(ia,0);

Refer to complete list of static functions at this link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics

Browser Support

atomics-browser-support

Conclusion

ECMAScript is making JavaScript sophisticated with new features and specifications year on year. The release process enables major browsers to adapt new specifications and make it ready to use for developers that desire bleeding-edge web technologies. Remember the table we discussed at the beginning of this article? Well keep a tab on Stage 3 specifications for upcoming features.

Refer to the process documentation in links and references section below for more details.

Links and References

Process documentation and stage definitions for ECMA Script https://tc39.github.io/process-document/

TC39 proposals https://github.com/tc39/proposals

Specification for Object.values and Object.entries https://github.com/tc39/proposal-object-values-entries

Specification for getOwnPropertyDescriptors https://github.com/tc39/proposal-object-getownpropertydescriptors

Finished proposals- TC39 https://github.com/tc39/proposals/blob/master/finished-proposals.md

APIs documentation by Mozilla

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer

This article was technically reviewed by Ravi Kiran.

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
V Keerti Kotaru has been working on web applications for over 15 years now. He started his career as an ASP.Net, C# developer. Recently, he has been designing and developing web and mobile apps using JavaScript technologies. Keerti is also a Microsoft MVP, author of a book titled 'Material Design Implementation using AngularJS' and one of the organisers for vibrant ngHyderabad (AngularJS Hyderabad) Meetup group. His developer community activities involve speaking for CSI, GDG and ngHyderabad.

Subscribe to V Keerti Kotaru's thoughts on Twitter @keertikotaru or at LinkedIn.



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook