ES6 Features

I have been using ES6/ES2015 for a few months in my full time job. Its been a gradual adoption process taking on the new features as and when we see fit. Over these months I have built up a list of my new goto patterns for JavaScript taking advantage of ES6.

Const & Let

Let

One of the biggest changes with ES6 is the addition of const and let. Let provides a means to define variables inside block scope. This can help to combat the existing hoisting problems with JavaScript.

// ES5
if (foo === 'foo')
   console.log(bar);
   var bar = 'bar'
   console.log(bar);
}

In the above example var will be hoisted and could potentially cause issues with the code.

// ES6
if (foo === 'foo')
   console.log(bar);
   let bar = 'bar'
   console.log(bar);
}

In the let example the variable will still be hoisted however the referencing of the variable will be done in the block before hand. This means that when running the ES5 code you will just see an undefined message for the first console. However in the let case you will get a reference error indicating that you have tried to use a var before it has been declared.

Const

Const provides a way to create a constant that is either global or local scoped. When defining a constant you must provide a value as the value cannot be changed later.

// define MY_CONST as a constant and give it the value 7
const MY_CONST = 7;
// this will fail silently
MY_CONST = 20;
// will print 7
console.log("my CONST is: " + MY_CONST);
// trying to redeclare a constant throws an error 
const MY_CONST = 20;
// the name MY_CONST is reserved for constant above, so this will also fail
var MY_CONST = 20; 
// MY_CONST is still 7
console.log("my CONST is " + MY_CONST);

There is some controversy around const as it’s not what some people might expect for example the code below will not throw an error:

const MY_CONST = {foo: 'bar'}
MY_CONST.foo = 'test'
console.log(MY_CONST) // Object {foo: "test"}

An alterative to const would be to use Object.freeze()

Arrow Functions

Arrow function provide a cleaner syntax for the standard function expression and it also binds the lexical this scope to the function. This not only makes the code look clean but also takes away the pain of scope binding. No more var that = this also all arrow functions are anonymous. You can use arrow functions in a number of ways:

 //ES6
(param) => { statements }
(param) => expression
param => { statements }
// A function with no parameters requires parentheses or an underscore:
() => { statements }
_ => { statements }

Spread

The spread operator provides a cleaner way of dealing with arguments or params for function. This becomes very useful when working with React and JSX as the below example shows:

var params = {foo: 'bar', bar: 'foo'};
//Without spread
<MyElement foo={params.foo} bar={params.bar} />

//With spread
<MyElement {...params}/>

In both examples the JSX element is getting the foo and bar params, the second is cleaner and also reduced the maintenance of the code. As the params object grows you do not need to update the JSX element declaration.

Parameter Destructuring

Parameter destruction is one of the gems I have found recently. It allows you to clean up the code when you know what you need from a param. An example of this would be a using a promise/async or callback function that returns you a result. In a lot of cases you only need one part of the response. You can now define what you want and ignore the rest.

//Without param destructuring
myfunction((err, result) => {
    if (!err) {
        console.log(result.body);
    }
});

//With param destructuring
myfunction((err, {body}) => {
    if (!err) {
        console.log(body);
    }
});

One gotcha I have found with this is when the code is transplied, when Babel transpliles the code it looks like this:

//Transplied
myfunction((err, _ref) => {
    var body = _ref.body;
    if (!err) {
        console.log(body);
    }
});

If the result param is undefined or null this will fail at run time, causing an unexpected error. This has caught me out before when the expected result was not defined and only failed while in production.

Object Literals

Last but not least Object literals. This is another clean syntax which I have been using alot. It provides a shortcut to defining variables.

var foo = 'bar';
var test = { foo };
console.log(test.foo); // 'bar';

This can also work when exporting modules, we have all seen the code below before:

function plus() {
    ....
}

function subtract() {
    ...
}

function total() {
    ....
}

module.exports = {
    plus: plus,
    subtract: subtract,
    total: total
};

This follows the revealing module pattern and is okay but we could use object literals to clean this up.

module.exports = { plus, subtract, total };

It’s a small change but reduces bulk and provides a clean and simple syntax to read.

That’s all for now

This is just a few examples of what I have been using but I’m still building up my list of ES6 features and hoping to get into some ES7 features soon. If you know of any other great features drop a comment.

 

chrislaughlin

 

Leave a Reply

Your email address will not be published. Required fields are marked *