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.

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)

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.

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).

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.

One of the use cases for the API is that the returned entries could be iterated through by creating a 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.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.

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

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

The resultant string will be of the length specified.

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.

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

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

The resultant string will be of the length specified.

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.

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.

This doesn’t affect length on function object.

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.

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:

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.

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

With the use of getOwnPropertyDescriptors, cloning can be done along with the descriptors.
Consider the following snippet:

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

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.

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

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

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.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
V Keerti Kotaru is an author and a blogger. He has authored two books on Angular and Material Design. He was a Microsoft MVP (2016-2019) and a frequent contributor to the developer community. Subscribe to V Keerti Kotaru's thoughts at his
Twitter account. Checkout his past blogs, books and contributions at
kvkirthy.github.io/showcase.