New Arrow Functions in ES6!

Zoe Madden-Wood ·

Among many of the new features of ES6, aka ECMAScript 2015, is the arrow function expression, also known as the fat arrow function. For those that have been programming in CoffeeScript, the syntax will look quite at home.


// ES6
// example 1
([param] [, param]) => {
statements
}
// example 2
param => expression

This corresponds to this syntax in the current standard JavaScript:


// ES5
// example 1
function ([param] [, param]) {
statements
}
// example 2
function (param) {
return expression
}

Essentially, it’s just a different way of specifying a function (of which there are a ton of different ways in ES6), but it’s not a direct replacement for function — you can’t do a ‘replace all’ in your code. Several important differences beyond syntactic sugar exist, including: 1) it creates a lexical this, 2) it implicitly returns an expression, and 3) it’s always an anonymous function. And that is where it gets interesting. To understand the problem the standards committee was trying solve, you first have to delve into context and the lexical this.

Before ES6, this was always scoped to the function, so each new function had its own this. This was especially difficult with object-oriented modes of programming.

If it’s a nested function and you want to grab the outside scope, then you have a few different ways to do that, but all of them seem a bit hacky. One of the most common that I see is to bind this to the lower scope.


function() { }.bind(this)

Another is to capture this in a variable, traditionally named self or something equivalent, and then use self or that instead of this.


function People() {
var self = this; // Some choose `that` instead of `self`.
self.size = 0;
setInterval(function addMorePeople() {
// The callback refers to the `self` variable of which
// the value is the expected object.
self.size++;
}, 1000);
}

ES6 solves the weirdness by having this be a reference to the enclosing scope, which sounds immensely useful and that’s certainly why the standards committee prioritized getting the arrow function in the 2015 standards release.


function People() {
this.size = 0;
setInterval(() => {
this.size++;
}, 1000);
}

The lexical this could create some confusion if you’re regularly using call() or apply(), since while you can pass in arguments, those have no effect on this.

As for the implicit return, for anyone who has ever spent half an hour trying to figure out why their code doesn’t work, only to discover they left out a single work return from their code, the implicit return in sheer joy in a bottle.


(param1, param2) => expression
// equivalent to: { return expression; }

Some of the downsides of using the arrow function are the same downsides with any anonymous function: 1) you can’t reference the function inside of the function easily — so no recursion, 2) it makes stack traces more difficult because it shows an anonymous function instead of a named function, and 3) it is slightly harder to figure out what the function does because it’s not explicitly named. Additionally, fat arrows are not the best for beginners to JavaScript. It’s very important to understand context before diving into using the lexical this.

There’s a few upsides though, which makes me very happy to be using them in a production app. It can increase readability dramatically by creating shortened anonymous functions inline. As mentioned, the ability to pass a reference to the enclosing scope is a huge benefit. It’s an overall win for code clarity in the cases where it’s a good fit, as with many functional patterns of programming. It’s a win either with functional or object-oriented programming.


var someArray = [1, 2, 3, 4]
someArray.map( num => num + 1);

(Some code examples and displays taken or inspired by MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)