Fat Arrow Functions in JavaScript

By | 2013/09/17

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;

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;

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.


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

24 thoughts on “Fat Arrow Functions in JavaScript

  1. abral

    Why can’t they be generators?
    It’d be awesome to use this kind of functions with Task.js!

    1. rob Post author

      I think the main reason you can’t use fat arrow functions as generators is that they lack a lot of the scope machinery full-fledged functions have on them. They’re “lighter”.
      Continuations have to maintain a lot of extra state to work and would violate the simplicity of these constructs. Generators are expensive.

  2. bomsy

    nice article rob.quite enlightening. if i’m correct this means that the fat arrow functions do not replace the current function convention.

    1. rob Post author

      Oh no, familiar function declarations will stick around. The world would break if that ever went away.

      Thanks for the comment!

  3. Neil Rashbrook

    In theory with the old DOM interfaces all you had to do was to define a handleEvent method on your prototype and use

    node.addEventListener(“click”, this);

    1. rob Post author

      Sure. I didn’t say this was the only way or even the best way to add an event listener. Just mentioning a pattern that has cropped up.

      Also, using a handleEvent method in an object leads to a lot of:

      switch(event.type) cases if you need to trap multiple events.

      But this was about fat arrow functions…

  4. Pingback: Fat arrow functions in Javascript | Rocketboom

  5. Pingback: YUI Weekly for September 20th, 2013 - YUI Blog

  6. tqwhite

    Is there any way to distinguish regular functions from fat arrow functions? It seems that, at invocation, it might be useful to know whether or not ‘this’ needs to be assigned.

    1. rob Post author

      tgwhite: that’s an interesting question. I bet you could use the fact that you can’t call “new” on a fat-arrow function to determine if it’s a regular function.

      typeof for both is “function”.

      Just for kicks:
      let isFatArrow = (functor) => {
      try {
      new functor();
      } catch(e) {
      return true;
      return false;

      function a() { return true };

      isFatArrow(isFatArrow); // true

      isFatArrow(a); // false

      works. (sorry for the crappy formatting)

  7. Jon

    This is pretty awesome, especially coming from a C# background. Is this currently available or is it coming out soon?

    1. rob Post author

      jon, this is currently available in Firefox 22 and up. As part of ES6, it should make it to V8 and IE sometime in the near future.

  8. Šime Vidas

    So, for the “let” statement to work, the code has to be placed in a script element with a type attribute that contains the “language” value, e.g. . On the other hand, arrow functions work in regular blocks. This should be noted in the article, since some people may try to test that code in their Firefox.

    1. rob Post author

      that’s really an issue with jsFiddle, not Firefox. If you run your example code directly in a Scratchpad or the Console it will work.

  9. ix

    A side-question, but why are you not using event.target directly in your function? Why the extra temporary value?

  10. Angelos Sphyris

    There is a slight error in your definition of fib

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

    You need to enclose n-2 in parentheses not a left parenthesis and a right curly brace.

    1. rob Post author

      right you are! I’ve fixed it.

      (we just proved Open Source works) 🙂

  11. CoDEmanX

    @rob: nice trick using “new”, but it can have side-effects. What about fn.hasOwnProperty(“prototype”) though? Apparently working in Firefox and iojs with –harmony_arraow_functions.


Put your words in the talk hole!