New ES2018 Features JavaScript Developers Should Know

ECMAScript (or ES), the specification that JavaScript is based on, is now on ECMAScript 2018 or the ES2018 version. The latest update was only released last June 2018. With each release, ES adds features and enhancements that improve its implementation. Since 2016, with ES2016, they have been updating it yearly with fewer added features in contrast to its previous iterations that took long periods of time.

Here are some of the new features of ES2018 that every JavaScript developer should know:

The Rest/Spread Properties

For ES2015, ECMA added the spread operator which is mostly used in variable arrays with more than one (1) expected value. This operator makes merging and copying a lot easier during implementation.

However, for ES2018, instead of using the previous concat() or slice() methods, you can now use the … operator.

In previous versions, the implementation went like this:

const array1 = [10, 20, 30];

// make a copy of array1
const copy = [...array1];

console.log(copy);    // → [10, 20, 30]

const array2 = [40, 50];

// merge array2 with array1
const merge = [...array1, ...array2];

console.log(merge);    // → [10, 20, 30, 40, 50]

Now, in ES2018, the spread property can be used for the same function but with a shorter implementation. This makes it easier for developers to pass arrays in separate arguments.

const array = [10, 20, 30]

// equivalent to
// console.log(Math.max(10, 20, 30));
console.log(Math.max(...array));    // → 30

This new feature is supported on the following versions:

Chrome
(Web, Mobile)
Firefox
(Web, Mobile)
Safari
(Web, iOS)
Edge
(Web, Mobile)
Samsung InternetAndroid Webview
60, 6055, 5511.1, 11.3N/A8.260

Asynchronous Iteration

Iteration or “looping” of data and functions is a significant part of programming. Previous versions of JavaScript offered syntax such as for, for…in, and while(). Iteration methods also existed through map(), filter(), and forEach().

ES2015 introduced iteration interface to enable programmers to process elements in a collection one after the other. Each object can be iterated using the Symbol.iterator property. Symbol.iterator is a dominant symbol that specifies functions that return iterators.

Plain objects are not necessarily iterable but they can be using the Symbol.iterator property. It can be seen through this example:

const collection = {
 a: 10,
 b: 20,
 c: 30,
 [Symbol.iterator]() {
   const vals = Object.keys(this);
   let i = 0;
   return {
     next: () => {
       return {
         val: this[vals[i++]],
         done: i > vals.length
       }
     }
   };
 }
};

const iters = collection[Symbol.iterator]();
 
console.log(iters.next());    // → {val: 10, done: false}
console.log(iters.next());    // → {val: 20, done: false}
console.log(iters.next());    // → {val: 30, done: false}
console.log(iters.next());    // → {val: undefined, done: true}


The code above works just fine but it is unnecessarily long and complicated, making the implementation longer. Using generator functions, the code can be converted into the following:

const col = {
 a: 10,
 b: 20,
 c: 30,
 [Symbol.iterator]: function * () {
   for (let key in this) {
     yield this[key];
   }
 }
};

const iter = col[Symbol.iterator]();
 
console.log(iter.next());    // → {val: 10, done: false}
console.log(iter.next());    // → {val: 20, done: false}
console.log(iter.next());    // → {val: 30, done: false}
console.log(iter.next());    // → {val: undefined, done: true}

The result is the same as the previous code but is relatively shorter. However, iterators are not suitable for representing asynchronous data sources. Because of this, ES2018 released asynchronous iteration and asynchronous iterables as solutions.

Conventional iterators, or just iterators, return plain objects in the form {value, done} where value is the next value in the sequence, and done is a Boolean that is true if there are no more values that follow in the sequence. Asynchronous iterators, on the other hand, return values that fulfill the context of the {value, done} format.

Here’s an example of the previous code using asynchronous properties:

const col = {
 a: 10,
 b: 20,
 c: 30,
 [Symbol.asyncIterator]: async function * () {
   for (let key in this) {
     yield this[key];
   }
 }
};

const iter = col[Symbol.asyncIterator]();
 
console.log(iter.next().then(result => {
 console.log(result);    // → {val: 10, done: false}
}));

console.log(iter.next().then(result => {
 console.log(result);    // → {val: 20, done: false}
}));

console.log(iter.next().then(result => {
 console.log(result);    // → {val: 30, done: false}
}));

console.log(iter.next().then(result => {
 console.log(result);    // → {val: undefined, done: true}
}));

This update is supported on the following:

Chrome
(Web, Mobile)
Firefox
(Web, Mobile)
Safari
(Web, iOS)
Edge
(Web, Mobile)
Samsung InternetAndroid Webview
63, 6357, 5712, 12N/A8.263

Promise.prototype.finally

The finally() method is used when you want to clean up after your operations have finished executing, regardless if the operation was successful or not. This is the latest addition in the ES2018 update. Although other JavaScript libraries have already implemented this similar method, Ecma has just added this for ECMAScript upon seeing its usefulness in many situations. Using this method, programmers can execute a code block regardless of the promised outcome.

For example:

fetch('https://www.google.com')
 .then((res) => {
   console.log(res.status);
 })
 .catch((error) => {
   console.log(error);
 })
 .finally(() => {
   document.querySelector('#spinner').style.display = 'none';
 });

For the example above, the finally() method simply hides the animated loading graphic after the data request has been processed. The function still executes whether the promise encounters an error or not.

Although you can get the same result using promise.then(func, func) instead of promise.catch(func).finally(func), you would still have to copy the same code from the fulfillment and rejection handlers or else, you would still have to declare a variable for it.

This update is supported on the following platform versions:

Chrome
(Web, Mobile)
Firefox
(Web, Mobile)
Safari
(Web, iOS)
Edge
(Web, Mobile)
Samsung InternetAndroid Webview
63, 6358, 5711.1, 11.118, N/A8.263

Template Literal Revision

A template literal is a kind of string literal that can span multiple lines and interpolate expressions including their results. When it is preceded by any expression, it will become a tagged template literal. This is used when parsing a template literal with a function. It is illustrated in the following example:

function fn(strings, replacement) {
 if(replacement === 'ES6') {
   replacement = 'ES2015'
 }
 return replacement + strings[1];
}

const version = 'ES6';
const result = fn`${version} was a major update`;

console.log(result);    // → ES2015 was a major update

From the example, you will see that the function is invoked and passed the template literal. The function modifies the value of the passed expression and returns the manipulated string.

Before this revision, there were syntax related restrictions with regards to tagged templates; any backlash followed by a certain sequence of characters were read as special characters. ES2018 removed this restriction from tagged templates and represented errors by invalid escape sequences as undefined.

This revision is available on the following versions:

Chrome
(Web, Mobile)
Firefox
(Web, Mobile)
Safari
(Web, iOS)
Edge
(Web, Mobile)
Samsung InternetAndroid Webview
62, 6256, 5611, 11N/A8.262
[Source code examples from css-tricks.com. All code is in JavaScript]
ES2018 framework is surrounded by its new and updated features mentioned in this article

Find JavaScript Developers at Full Scale!

At Full Scale, we hire top tier developers who are skilled and experienced in multiple JavaScript platforms and libraries. They are skilled in multiple development tools and processes that involve JavaScript including ECMAScript 2018!

Through our Guided Development process, we will give you the overview and full control of the development process while we take care of recruiting, assessing, and employing the top developers that we can find to work on your project. You don’t have to worry about the tedious process of hiring developers on your own.

Get to know more about us through our website or byshooting us a message!