At the end of June the new Javascript standard, ES2017 , popularly known as ES8, was approved . As always, I’ll explain all the news in detail so you can stay up to date ūüėČ

What are the news?

Surely you will know that since 2015 it was agreed to update the Javascript standard every year in order to keep JS up to date in a smooth way. The changes of last year were very decaffeinated, but this year we have some juicier news.

Quickly listing the news, they are:

  • Asynchronous flow of functions with async and await
  • Object.entries and Object.values
  • List properties with Object.getOwnPropertyDescriptors
  • Padding of Strings
  • Shared memory and atomic access
  • Commas at the end in lists of parameters and calls to functions

Functions async and expression await

The killer feature of ES8 and the most anticipated novelty.

The functions asyncsimplify the control of asynchronous flows, avoiding Promise.thencontinuous nesting and reducing the amount of code.

By declaring a function with the modifier async, you get an object AsyncFunction, which consists of a block of code that will be executed asynchronously. When you call AsyncFunction, you always get a promise.

The fun of the functions asyncis that they can contain expressions await, which are used to pause the execution of the function asyncuntil a promise is resolved, returning its result.

I teach it to you with an example that you will understand better: I will create a pair of promises, and then a function asyncthat will use expressions awaitto control the flow of previous promises.

//promise (ES6) which returns a user asynchronously
function fetchUser(authToken) {
  return new Promise(resolve => { 
    setTimeout(() => {  resolve({name: "Chuck Norris"}); }, 2000);
  });
}

//promise (ES6) which validates a user and returns its authentication token if correct, or an error otherwise.
function authUser(id, pwd) {
  return new Promise((resolve, reject) => { 
    setTimeout(()=>{
      if(pwd == 'pass'){
        resolve({authToken: "1234"});
      }else{
        reject("invalid password");
      }      
    }, 2000);
  });
}

/* ---------------------- */
/* Here the chicha starts */
/* ---------------------- */

//async function (ES8), makes a login (receives id and pwd) and returns the user
async function login(id, password){
  try{
    //await (ES8): for the function until resolving authUser
    const authToken = await authUser(id, password);

    //await (ES8): for the function until you solve fetchUser    
    const user = await fetchUser(authToken);

    //finally I return the user
    return user;
  }
  catch(err){
    //I can throw errors, which the async function will return as "rejects".
    throw new Error(err);
  }
}

Notice how the function asyncof login used awaitto simplify the mechanism pending resolution with promises authuser and fetchUser. 

Also, you could use this login function as a promise either.

login('Chuck Norris', 'pass')
  .then(user => console.log(user))
  .catch(err => console.log(err));

console.log("end");

//the output by console will be:
// -> end
// ---- 4s ---> Chuck Norris

Of course, login works asynchronously and since it takes 4 seconds (2 for authentication and 2 for the user’s fetch ), the message ” end ” is logged before the console .

Of course, if the password was incorrect, the login function would throw an error that would be detected in the catch .

login('Chuck Norris', 'NO-pass')
.then(user => console.log(user))
.catch(err => console.log(err));

console.log("end");

//the output by console will be:
// -> end
// ---- 2s ---> invalid password

IMPORTANT: The expression awaitcan only be used within functions async.

In addition, the class syntax introduced with ES6 also allows methodsasync . The previous example could be put in a class, in the following way:

//async - await syntax, in ES6 classes
class AuthService{
  fetchUser(authToken) { /*...*/ }

  authUser(id, password) { /* ...*/ }

  async login(id, password){
      const authToken = await this.authUser(id, password);
      const user = await this.fetchUser(authToken);
      return user;
  }
}


let auth = new AuthService();

auth.login('Chuck Norris', 'pass')
.then(user => console.log(user))
.catch(err => console.log(`err is ${err}`));

Object.entries and Object.values

These two new methods are added to the class Objectto iterate over the enumerable properties of an object. The result follows the same order as the loops for in.

The names of the methods are quite self-explanatory. Here is an example of what they do:

const data = { a: 'Hello', b: 1 };
Object.values(data); // ['Hello', 1]
Object.entries(data); // [['a', 'Hello'], ['b', 1]]

Remember that arrays treat their elements as an object with numerical properties starting at zero.

const obj = ['a', 'z', '5']; // equals to { 0: 'a', 1: 'z', 2: '5' };
Object.values(obj); // ['a', 'z', '5']
Object.entries(obj); // [['0','a'], ['1','z'], ['2','5']]
Object.values('az5'); // ['a', 'z', '5']
Object.entries('az5'); // [['0','a'], ['1','z'], ['2','5']]

Also, for inorder the numeric keys in ascending order.

const obj = { 2: 'a', 1: 'b', 3: 'c' };
Object.values(obj); // ['b', 'a', 'c']
Object.entries(obj); // [['1','b'], ['2','a'], ['3','c']]

Padding of Strings

The string object receives these 2 new methods to fill a string, either forward ( padStart) or behind ( padEnd), in order to reach a certain size.

In addition, you can pass a string with the content of fill (otherwise, use spaces).

This is how padStart is used

'bar'.padStart(1);          // 'bar'
'bar'.padStart(4);          // ' bar'
'bar'.padStart(4, 'foo');   // 'fbar'
'bar'.padStart(10, 'foo');  // 'foofoofbar'
'bar'.padStart(5, '0');     // '00bar'

This is how padEnd is used

'foo'.padEnd(1);          // 'foo'
'foo'.padEnd(4);          // 'foo '
'foo'.padEnd(4, 'bar');  // 'foob'
'foo'.padEnd(10, 'bar');  // 'foobarbarb'
'foo'.padEnd(5, '1');     // 'foo11'

Object.getOwnPropertyDescriptors

The method getOwnPropertyDescriptorsreturns all the property descriptors of the object (not inherited by its prototype). This method was born with the aim of facilitating cloning between 2 objects, something that until now had to be done by hand in Javascript.

Here are a couple of examples of common mechanisms that benefit from this method:

const shallowClone = (object) => Object.create(
  Object.getPrototypeOf(object),
  Object.getOwnPropertyDescriptors(object)
);

const shallowMerge = (target, source) => Object.defineProperties(
  target,
  Object.getOwnPropertyDescriptors(source)
);

Besides the cloning of objects, this method will be of special interest in the future, when the decorators are approved (or right now if you work with TypeScript), since the property descriptors are commonly used in their definition.

Shared memory with atomic access

If you have worked in multithread languages ‚Äč‚Äčlike C, you will perfectly understand the concept of atomic access.

Basically, when 2 threads have access to a shared memory space, it is important that the write or read operations are atomic, that is, done in block and without interruptions of other threads, to guarantee the validity of the data.

This functionality is designed for web workers, since it is the only case in which you will find multithreading in Javascript, and at the moment it is oriented to very low level ( ArrayBuffers: arrays of binary data).

The mechanism consists of:

  • SharedArrayBuffer: A new constructor to create ArrayBuffersshared memory.
  • The class Atomic, with static methods to access / manipulate it SharedArrayBufferin an atomic manner.

This is something that surely you will not use in your day to day. In case you need it, you can find more details here .

Comas at the end of parameters and functions

So far, if after the last parameter in the definition of a function or its call, you put a comma … BIIIP !!! ERROR, there was an exception!

As of ES8, Javascript will no longer complain about those extra commas, it will simply ignore them:

//trailing commas in declaration
function foo(a, b, c,) { /* ... */ }

//trailing commas in execution
foo("x", "y", "z",);

Conclusions

The inclusion of async functions was one of the most anticipated developments for this year, and I am happy that it has finally been incorporated into Javascript. I was left with the desire, that yes, that included also the decorators, to which so much match them in TypeScript . The rest (except for atomic access) are small utilities that are used regularly and will save you several lines of code

If I have to get wet for next year, my bet is that the new killer feature will be, finally, the decorators .

And you? What do you think will be the main novelty for ES9?

Author

Am horla

Pin It