windmills panorama

Hard to beat C# and CoffeeScript here
– Brendan Eich, Arrow Function Syntax Rationale

Since sometime back in the heady days of Firefox 22, Firefox gained the ability to use Fat Arrow Functions in JavaScript. Users of CoffeeScript (or, I guess, C#) will be familiar with the syntax. We’ve been using these in Firefox DevTools code for nearly 6 months.

You can use them today in any shipping Firefox and experiment with them live in the Scratchpad or Console.

They look like this:

let x = (args) => { /* some function gunk */ };

If you want to call it, you can with x();

Fat Arrow functions have a couple of interesting properties. First and probably most useful is that they gain the scope of the environment they’re defined in. You can’t change the value of this by using a call() or bind() function.

Second, Fat Arrow functions don’t have their own prototype or a constructor. (They have the standard Function prototype). This means trying to use the new operator on a fat arrow function results in a TypeError.

That’s all well and good, but what is the practical application of all of this? If you’re a JavaScript programmer, chances are you’ve seen (and done) something like this before:

var listener = node.addEventListener("click", function(event) {
    let _target = event.target;
    this.handleClick(_target);
}.bind(this));

Inside we call a local method called handleClick() with the event’s target property. Nothing too exciting.

With Fat Arrow Functions, that becomes:

var listener = node.addEventListener("click", (event) => {
    let _target = event.target;
    this.handleClick(_target);
});

Look at all that saved typing!

The real benefit of course is that you don’t have to go through the mental hoop-jumping of trying to figure out what scope your function is going to run in (and more often-than-not, you just wanted it to run inside the current scope the function is being defined in anyway).

It just does the right thing.

Some interesting facts about Fat Arrow Functions

You can use them recursively. Because the containing scope closes over the fat arrow function, you can do things like,

let fib = (n) => {
    if (n <= 1) return 1;
    return fib(n - 1) + fib(n - 2);
}

You can’t use fat arrow functions as Generators. Deep continuations are not allowed. Fat Arrow functions are intended to be super light.

The “=>” syntax behaves like a “low-precedence assignment” operation. In

let x = () => { }

the order of operation is from left to right.

Update!

I didn’t include it originally, but some Fat Arrow Enthusiasts encouraged me to mention expression function syntax.

let square = (x) => { return x * x };

is equivalent to:

let square = x => x * x;

For single arguments, you can leave off the ()s. And for function expressions, you can lose the {}s and the return statement. Note that you cannot even use a return statement in this case as it’ll generate a syntax error about a missing semicolon. Don’t even try it!


Trajectory Book 1 Cover

Trajectory Book 1 (Hard Scifi, 65k words)

Four mining ships are making the slow return to Mars from operations in the asteroid belt. Back on the planet, a group of students discover a mysterious object in space in an impossible orbit. The crew of the Lighthouse space station are shocked by a devastating accident that throws their routine into chaos as they strive to get their ships safely home.

Amazon US, Amazon Canada, Smashwords (epub), Kobo, iTunes