Exploring ES6 — Arrow Functions

Learn about ES6 arrow functions, what they are, how they compare to traditional functions and how to use them in your code today.

Arrow functions are one of the most talked about ES6 features. It was in the similar fat arrow syntax in coffeescript that I first understood the usefulness of the feature. Now it’s implemented in Javascript along side the new class and string interpolation features I don’t feel so bad about leaving Coffeescript behind.

Syntax

Let’s first take a look at the syntax. It can be broadly broken into two types Expression body and statement body.

Expression bodies

Single arguments can be written without brackets. The expression’s return value is implicit.

var printValue = printThis => printThis;

// Traditional equivalent
var printValue = function(printThis) {
  return printThis;
}

Multiple arguments must be comma separated and contained inside brackets.

var multiply = (a, b) => a * b;

// Traditional equivalent
var multiply = function(a, b) {
  return a * b;
}

Arrow functions without arguments must have empty brackets.

var sayHello = () => console.log('Say Hello');

// Traditional equivalent
var sayHello = function() {
  return console.log('Say Hello');
}

Statement bodies

If your function must contain more than one expression a statement body can be used.

var greet = (name) => {
  return 'Hello ' + name;
}

// Traditional equivalent
var greet = function(name ) {
  return 'Hello ' + name;
}

Invoking Arrow Functions

Arrow functions, like traditional functions can be immediately invoked.

(name => "Hello " + name)("Will");

// Traditional equivalent
(function( name ) {
  return 'Hello ' + name;
})("Will");

Scope

One of biggest differences between the arrow and traditional functions besides syntax is the context of this. In traditional functions this changes depending on where it is called. This led to the use of closing over the outer context of this by saving it in a variable usually named ‘self’ or 'that’. Alternatively the function’s bind method could me used to explicitly pass in the value this.

With arrow functions we no longer have to worry about context. The value of this is lexical, in other words it takes on the context of where ever it is defined.

// Traditional way to handle passing in correct scope
// to an event handler.
var Greeter = {
  init: function() {
    document.addEventListener("click", (function(e) {
      this.handleIt();
    }).bind(this), false);
  },

  handleIt: function(e) {
    console.log('You clicked');
  }
}


// Simplification using arrow function which
// maintains the outter scope.
var Greeter = {
  init: function() {
    document.addEventListener("click", e => this.handleIt(e), false);
  },

  handleIt: function(e) {
    console.log('You clicked');
  }
}

Advantages

Arrow functions offer up a couple of advantages over the traditional function. To me the most apparent is the simple and concise nature of the syntax. The combination of the removal of brackets and implicit returns make code more readable for some use-cases.

Preference of using arrow functions over traditional functions has the potential to cut code complexity. Lexical this removes the overhead of working out the context of this in a particular scenario.

I’ve seen it hinted at that arrow functions are more performant. The consistency of ‘this’, means javascript engines can be optimised.

Using Arrow Functions

At the time of writing ES6 is projected to be ratified as a standard in June 2015. According to kangax’s compatibility table. Firefox and Edge are the closest to supporting it. If you want to use this and other ES6 features staright away and still support legacy browsers, I recommend Babel.js transpiler, which caters for a range of build systems and frameworks.

comments powered by Disqus