Programming

5 Modern JS Features (ES6+)

While ES6 isn’t exactly “new”, it remains the most comprehensive series of changes since ES5 in 2009. I have selected 5 of the most useful (in my opinion) ES6+ features that I feel will improve the way you write JavaScript.

1. Async/Await (ES8)

Simply put, async/await is an improved way to write asynchronous code. Why you ask? This is because it is written like synchronous code which improves its readability. Additionally thanks to the tried and true try/catch block, you can catch rejected promises for multiple await statements. Before promises were even formally integrated into the language, we used callback functions to execute asynchronous code like this:

const myFunc = someArg => {
    firstFunc(someArg, () => {
        secondFunc(someArg, () => {
            thirdFunc(someArg, () => {
                // you get the point
            });
        });
    });
};

And then we used promise chaining with .then()and with .catch() to catch errors like this:

const myFunc = someArg => {
    firstFunc(someArg).then(result => {
        secondFunc(result).then(result => {
            thirdFunc(result).then(result => {
                // do something with the result
            }).catch(err => console.log(err));
        }).catch(err => console.log(err));
    }).catch(err => console.log(err));
};

That same block of code can be written using async/await like this:

const myFunc = async someArg => {
    try {
        const firstResult = await firstFunc(someArg);
        const secondResult = await secondFunc(firstResult);
        const thirdResult = await thirdFunc(secondResult);
        // do something with thirdResult
    } catch (err) {
        console.log(err)
    };
};

Much better if you ask me!! Notice the async keyword declared in our function. This enables to use await. IF we were handling the errors differently for each returned promise, you would use separate try/catch blocks.

2. Arrow Functions (ES6)

Another improvement to the language was arrow functions. It provides a more concise syntax, implicit return (for single line bodies), and you can omit the parentheses if the function contains only one argument. For example:

const myFunc = function(name) {
    return name;
};

Could be written as:

const myFunc = name => name;

3. Destructuring Assignment (ES6)

Using destructuring assignment, you can assign and access values within arrays and objects more easily than dot walking.

Arrays

const arr = [1, 2, 3];
const [a, b] = arr;
console.log(a);
// 1
console.log(b);
// 2

Basic destructuring of an array:

You can also skip over assigning indexes within the array using the below syntax:

const arr = [1, 2, 3];
const [a,,b] = arr;
console.log(a);
// 1
console.log(b);
// 3

You can also use the ... syntax (more on this later) to assign the rest of the array to a variable like this:

const arr = [1, 2, 3, 4, 5];
const [a, ...b] = arr;
console.log(a);
// 1
console.log(b);
// [ 2, 3, 4, 5 ]

Objects

Basic destructuring of an object:

const obj = {a: 1, b: 2, c: 3};
const {a, b} = obj;
console.log(a);
// 1
console.log(b);
// 2

What about destructuring nested objects?

const obj = {
    a: {
        b: 2,
        c: 3
    }
};
const {a: {b}} = obj;
console.log(b);
// 2

It can also be particularly useful to assign destructured values an alias. Perhaps there is a more appropriate name you’d like to give that value instead of what it’s called in the object.

const obj = {a: 1, b: 2, c: 3};
const {a: myAlias} = obj;
console.log(myAlias);
// 1

4. Rest Parameters/Spread Operator (ES6)

The rest/spread operator looks like this ... and what it essentially does is expand or condense objects.

Arrays

The below is an example of rest parameters. It is useful for creating functions that take an indefinite number of arguments. We also use the spread syntax on our parameter to use every value of the array as an argument in the given function.

const arr = [1, 2, 3];
const myFunc = (...args) => {
    args.forEach(arg => console.log(arg));
};
myFunc(...arr);
// 1
// 2
// 3

Notice we must use ...arr when we call myFunc(). This is because we want the arguments to be 1, 2, 3 and not [1, 2, 3]. If we did not spread the array, we get the following:

myFunc(arr);
// [ 1, 2, 3 ]

You can also use the spread syntax to easily concatenate arrays.

const arr = [1, 2, 3];
const anotherArr = [4, 5, 6];
console.log([...arr, ...anotherArr]);
// [ 1, 2, 3, 4, 5, 6 ]

Objects

You can use the spread syntax on an object to change and/or add key/value pairs:

const obj = {a: 1, b: 2, c: 3};
console.log({...obj, c: 4, d: 5});
// { a: 1, b: 2, c: 4, d: 5 }

Similarly, you can also use it to merge 2 objects together:

const obj = {a: 1, b: 2, c: 3};
const anotherObj = {c: 4, d: 5, e: 6};
console.log({...obj, ...anotherObj});
// { a: 1, b: 2, c: 4, d: 5, e: 6 }

5. Default Parameters (ES6)

Default parameters are useful for defining your own default values for a given parameter. If you don’t, the values are undefined. Previously you’d have to check for undefined values within your function, but with default parameters you can assure that value is whatever you want it to be, if it is not supplied.

const greet = (name = 'buddy') => {
    console.log(`hey ${name}`);
};
greet('Aaron');
// hey Aaron
greet();
// hey buddy

Need more information? Check out https://developer.mozilla.org/en-US/