Useful New Features in ES2016 and 2017
By: John Au-Yeung
Tags: Technology, Programming, JavaScript, Arrays, Software Development

ES2017 Features

Object.values

The Object.values lets us get an array with the values of an object in an array. The values are returned in the same order as it is provided by the for...in loop, except that Object.values do not return values that are in the prototype chain.

For example, we can write:

const obj = { a: 1, b: 2 };

console.log(Object.values(obj)); // [1, 2]



const obj = { 0: 'd', 1: 'e', 2: 'f' };

console.log(Object.values(obj)); // ['d', 'e', 'f']



const obj2 = { 100: 'd', 2: 'e', 7: 'f' };

console.log(Object.values(obj2)); // ['e', 'f', 'd']



console.log(Object.values('abc')); // ['a', 'b', 'c']

As we can see, Object.values works with objects and strings. If the keys are numbers, then they are returned in with the keys in increasing order, like in the obj2 example above. For strings, it returns an array of the individual characters of the string.

Object.entries()

The Object.entries function returns an array with each entry being the key-value pairs in their individual arrays. The entries are returned in the same order as it is provided by the for...in loop, except that Object.values do not return values that are in the prototype chain. As with any object, we can sort the array to get the entries in the order we want with the sort function.

For example, we can write:

const obj = { foo: 1, bar: 2 };

console.log(Object.entries(obj)); // [ ['foo', 1], ['bar', 2] ]



const obj = { 0: 'x', 1: 'y', 2: 'z' };

console.log(Object.entries(obj)); // [ ['0', 'x'], ['1', 'y'], ['2', 'z'] ]



const obj2 = { 100: 'x', 2: 'y', 7: 'z' };

console.log(Object.entries(obj2)); // [ ['2', 'x'], ['7', 'y'], ['100', 'z'] ]



console.log(Object.entries('abc')); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]



console.log(Object.entries(100)); // [ ]



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

for (const [key, value] of Object.entries(obj)) {

console.log(`${key} ${value}`); // "a 1", "b 2", "c 3"

}



Object.entries(obj).forEach(([key, value]) => {

console.log(`${key} ${value}`); // "a 1", "b 2", "c 3"

});

In the above examples, we can see that Object.entries return an array of key-value pairs with each entry as an array with the key being the first element and the value being the second element. If the keys are integers, then they are sorted in ascending numerical order. So Object.entries(obj2) returns [ ['2', 'x'], ['7', 'y'], ['100', 'z'] ] . It also works with strings with the individual characters return with the index of the characters as the key, so the key is the index of the string, which is the first element of each entry, and the individual character is the value of the string, which is returned as the second character. For objects that have no properties, like numbers and booleans, Object.entries returns an empty array.

The array returned by Object.entries can be converted to a Map object. It can be used like in the following example:

const obj = { a: 1, b: 2 };

const map = new Map(Object.entries(obj));

console.log(map); // Map { a: 1, b: 2 }

String.padStart()

The padStart() function adds a string the number of times before a string until it reaches the length that you specify. The function takes two parameters. The first is the target length of your string. If the target length is less than the length of your string, then the string is returned as is. The second parameter sis the string that you want to add the padding with. It’s an optional parameter and it defaults to ' ' is nothing is specified.

For example, we can write the following:

' def '.padStart(10); // " def "

' def '.padStart(10, "123"); // " 1231231def "

' def '.padStart(6,"123465"); // " abcdef "

' def '.padStart(8, "0"); // " 00000def "

' def '.padStart(1); // " def "

Note that each string is filled up to the target length with the string in the second argument. The whole string in the second argument may not always be included. Only the part that lets the function fill the string up to the target length is included.

String.padEnd()

The padEnd() function adds a string the number of times after a string until it reaches the length that you specify. The function takes 2 parameters. The first is the target length of your string. If the target length is less than the length of your string, then the string is returned as is. The second parameter is the string that you want to add the padding with. It’s an optional parameter, and it defaults to ' ' is nothing is specified.

For example, we can write the following:

' def '. padEnd (10); // " def "

' def '. padEnd (10, "123"); // " def1231231 "

' def '. padEnd (6,"123465"); // " defabc "

' def '. padEnd (8, "0"); // " def00000 "

' def '. padEnd (1); // " def "

Object.getOwnPropertyDescriptors()

The Object.getOwnPropertyDescriptors() function returns all the property descriptors of an object.

For example, we can use it like the following code:

const obj = {

a: 1

}; const descriptors = Object.getOwnPropertyDescriptors(obj);

The descriptors object should have:

{

a: {

configurable: true,

enumerable: true,

value: 1,

writable: true

}

}

Async and Await

With async and await , we can shorten promise code. Before async and await , we have to use the then function, we make to put callback functions as an argument of all of our then functions. This makes the code long is we have lots of promises. Instead, we can use the async and await syntax to replace the then and its associated callbacks as follows. For example, we have the code to make requests to the back end with the Fetch API:

const APIURL = " http://localhost:3000 "; const subscribe = async data => {

const response = await fetch(`${APIURL}/subscribers`, {

method: "POST",

mode: "cors",

cache: "no-cache",

headers: {

"Content-Type": "application/json"

},

body: JSON.stringify(data)

});

return response.json();

}; window.onload = () => {

nameForm.method = "post";

nameForm.target = "_blank";

nameForm.action = "";

nameForm.addEventListener("submit", async e => {

e.preventDefault();

const firstName = document.getElementById("firstName").value;

const lastName = document.getElementById("lastName").value;

const email = document.getElementById("email").value;

let errors = [];

if (!firstName) {

errors.push("First name is required.");

} if (!lastName) {

errors.push("Last name is required.");

} if (!email) {

errors.push("Email is required.");

} if (!/[^@]+@[^\.]+\..+/.test(email)) {

errors.push("Email is invalid.");

} if (errors.length > 0) {

alert(errors.join(" "));

return;

}

try {

const response = await subscribe({

firstName,

lastName,

email

});

alert(`${response.firstName} ${response.lastName} has subscribed`);

} catch (error) {

alert(error.toString());

}

});

};

We replaced the then and callbacks with await . Then we can assign the resolved values of each promise as variables. Note that if we use await for our promise code then we have to put async in the function signature like we did in the above example. To catch errors, instead of chaining the catch function at the end, we use the catch clause to do it instead. Also, instead of chaining the finally function at the bottom to run code when a promise ends, we use the finally clause after the catch clause to do that instead.

In the code above, we got the resolved value of the promise assigned to a variable instead of getting the value in the callback of the then function, like in the const response = await subscribe({...}) line above.

async functions always return promises and cannot return anything else like any other function that uses promises. In the example above, we used the promised based Fetch API and async and await syntax, we showed that we can chain promises in a much shorter way than with the then function with callbacks passed in as an argument.

ES2016 and 2017 gave us convenient features that enhance the already great syntactic sugar and functions that were added to ES2015, which was a significant improvement over its predecessor. These two versions of JavaScript make JavaScript development even better with new Object, string, and Array methods and shorthand for chaining promises.