Blog of The Ultimate Resource on Node.js: Tutorials, Tips and Updates

Recently I wrote a blog post and even created an online course on ES6/ES2015. Guess what? TC39—the mighty overseer of JavaScript—is moving forward with ES8 so let’s cover ES7 and ES8 (or ES2016 and ES2017 officially). Luckily, they are much, much, much smaller than the best of a standard that was ES6. Really! ES7 has only two (2) features!

ES7 features:

Array.prototype.includes

Exponentiation OperatorES8 is not finalized yet as of this writing (Jan, 2017) but we can assume all finished proposals (stage 4) and most of stage 3 (more on stages here and in my course). The finished 2017 (ES8) proposals are:

Object.values/Object.entries

String padding

Object.getOwnPropertyDescriptors

Trailing commas in function parameter lists and calls

Async Functions

I won’t include stage 3 proposals in this post, but you can check the status of proposals from stage 1 to 3 here.

Let’s dive deeper into the proposals and features.

Array.prototype.includes

With Array.prototype.includes everything is easy and simple. It’s a replacement for indexOfwhich developers used to check for presence of a value in an array. indexOf is kind of awkward to use because it returns the position of an element in array or -1 in case such an element could not be found. So it returns a number, not a boolean value. Developers need to implement additional check. In ES6, to check the presence of a value you had to do a little dance like the code shown below, because when there’s no match, Array.prototype.indexOf returns -1 which is truthy (evaluates into true), but when the matching element has index of 0, the array does contain element, but 0 evaluates into false:

In addition to being more eloquent and actually giving developers the boolean value instead of position of a match, includes also works with NaN (not a number). Finally, includes has fromIndex second optional parameter. This is good for optimization, because it allows to look for a match starting at a certain position.

All in all, includes brings simplicity to any developer who has to check if a value is in an array/list… which is like almost all of us. Rejoice!

Exponentiation Operator

This operator is mostly for developers doing some math and is useful in case of 3D, Virtual Reality, SVG or data visualization. In ES6 and prior, you had to either create a loop, create a recursive function or use Math.pow. If you forgot what exponent is, it’s when you multiply the same number (base) over itself many times (exponent). For example, 7 power of 3 is 7 * 7 * 7.

So in ES6/ES2015, you can use Math.pow or create a small recursive arrow function:

Many new ES features are borrowed from other languages (CoffeeScript - love it, Ruby, etc.) As you can guess, exponential operator exists in other languages:

Python: x ** y

CoffeeScript: x ** y

F#: x ** y

Ruby: x ** y

Perl: x ** y

Lua, Basic, MATLAB: x ^ y

Not having an exponential operator in JavaScript was never a problem for me personally. :) I never wrote anything exponential in my 15 years of writing JavaScript besides interviews and coding tutorials like this one… Was the lack of an exponential operator a big miss for you?

Object.values/Object.entries

Object.values and Object.entries are in ECMAScript2017 spec and, similarly to Object.keys, return arrays. The ordering of these arrays matches Object.keys ordering.

Each items of arrays returned by Object.keys, Object.values and Object.entries , correspondingly contain the key, value, or entry for that particular object property/attribute.

Before ES8/ES2017, JavaScript developers who needed to iterate over own properties of an object had to use Object.keys, iterate over an array returned by it and use obj[key] to access each value:

You can also use good old for/in (ES5), but that will iterate over all enumerable properties (like the one in prototype or with names - see MDN), not just own properties, which may accidentally spoil the result with unexpected values like prototype or toString.

Object.values returns an array of object’s own enumerable property values. We can iterate over it using good Array.prototype.forEach, but with ES6 arrow function and implicit return:

Extracting values and key-value pairs from objects are now even easier! Object.values and Object.entries do that in a way not unlike to Object.keys (own properties only + order is the same). Together with for/of (ES6), we can not only extract but iterate over them.

String padding with padStart and padEnd

String.prototype.padStart and String.prototype.padEnd make working with strings in JavaScript a more pleasant experience and help avoid depending on extra libraries.

padStart() returns a string of a given length (targetLength) by inserting pads at the beginning. Pads are a given string, repeated if needed until the desired length is reached. Left is the beginning of a string (at least in most Western languages). A typical example is creating columns with an empty space:

Object.getOwnPropertyDescriptors

The new Object.getOwnPropertyDescriptors returns all own property descriptors of an object obj. It’s a plural version of Object.getOwnPropertyDescriptor(obj, propName) which returns only a single descriptor of the property propName of obj.

In our day and age of immutable programming, this method comes in handy (remember, objects are passed by reference in JavaScript!). In ES5, developers would use Object.assign() to copy objects. However, Object.assign() assigns properties versus just copying or defining new properties. This might cause problems when using more complex objects or classes’ prototypes.

Object.getOwnPropertyDescriptors allows to create real shallow copies of objects and to create subclasses. It does so by giving developers the descriptors. Putting descriptors in Object.create(prototype, object) give a real shallow copy:

That’s the usage for Object.getOwnPropertyDescriptors, but what is a descriptor? It’s an object which describes. Duh.

Okay, okay. Let’s discover descriptors a little bit more. In JavaScript, there are two types of descriptors:

Data descriptor

Accessor descriptor

Accessor descriptor has mandatory properties: get or set or both get and set which you can guess are getter and setter functions. Then accessor descriptor could have optional properties: configurable and enumerable

Trailing commas are mostly useful when using multi-line style (typically with lots of long argument names). Developers can finally forget about using the weirdly-looking comma-first approach, since comma bugs were their main reason for using it. Now, you can have commas everywhere, even after the last argument.

Async Functions

Asynchronous functions (or async/await) feature operates on top of Promise, so you might want to read up on them or watch a video course for a refresher. The idea is to simplify writing asynchronous code because… well, because human brain sucks at thinking in parallel non-sequential way. It just didn’t evolve that way.

Personally, I never liked Promises. They are very verbose, compared to just callback, so I never got to use them. Luckily, with ES8, async functions are much more eloquent. Developers can define an asyncfunction which may or may not contain await for promise-based asychronous operations. Under the hood, an async function is a function that returns Promise, however you won’t see such a word anywhere in its body (unless you explicitly use it, of course).

For example, in ES6 we can use Promise and Axios library which makes a request to a GraphQL server:

You can see this code working in (Babel REPL). Take note that, in this case, instead of Axios, there’s mock library with similar behavior, but with setTimeout being called instead of real HTTP requests:

With async/await, your code performs asynchronously but looks like synchronous. It’s easier to read such code from top to bottom and understand what it is doing, because the order of results appearing along with execution of function body goes precisely from top to bottom.

Wrap-Up

That’s more or less all for the ES8 (not finalized yet) and definitely ES7 (finalized). You can use all of these and many more stage 0-3 features NOW, whithout having to wait for browsers to implement them, if you use Babel, Traceur or a similar too. The ES7 and ES8 code will simply convert to ES5-compatible code. Even Internet Explorer 9 will grog it. :)

Some ES8 features to watch out for because they are currently in stage 3 but are very likely to end up in ES8/ES2017:

0 comments

ABOUT

This is the official blog of Node University: The Ultimate Resource on Node.js. You can find here the top resources on Node.js, JavaScript, cloud, React and software engineering. For free video previews, view courses at https://node.university/courses.