In today's post I will talk about fat-arrow functions introduced in ES6. Why is it called fat-arrow function you wonder? As it turns out, => is called fat-arrow in contrast to -> for example which, I guess, should be called slim-arrow. Anyhow, ES6 functions are called fat-arrow functions because they incorporate fat-arrow in its syntax. Let's look at an example and compare regular ES5 functions with newly introduced ES6 functions.

// ES5
const add = function(a, b) {
    return a + b;
}

// ES6
const add = (a, b) => {
    return a + b;
}

Notice how we no longer have to declare function keyword and instead just use parameters list surrounded by parentheses followed by fat arrows. Just by itself it's a small improvement over the existing syntax.

What I find really cool about fat-arrow functions is implicit returns. Notice how in the example below we no longer explicitly return anything. By removing curly braces we are automatically returning the result of the expression a + b.

const add = (a, b) => a + b;

Another interesting property of ES6 arrow functions is that if the function has a single argument, you can omit parentheses around the parameter list and use a single argument instead.

It might become clearer with an example. Notice how in the example below we list number as a parameter and we no longer surround it by parentheses. Nothing too fancy here but just another way to increase legibility of one's code.

const double = number => number * 2;

Another propery of fat-arrow functions that is worth mentioning is that it does not have its own this binding and instead retains the context of its enclosing lexical context.

In the example below we have two object literals that have a function getSummary that returns a list of person's hobbies. Note how in the ES5 version we have to declare self variable to keep track of this context. This is because the function passed to hobbies.map creates its own this binding and we can no longer access person's name.

Alternatively, in ES6 version the binding of this is the same as its parent and thus we retain the person's name inside the function passed to hobbies.map. This is great in cases like this where we want to retain this binding of function's parent but it's not so great if we want a function to have its own this binding. Then regular ES5 functions should still be utilized.

// ES5
const person = {
  name: 'Homer',
  hobbies: ['beer', 'tv', 'cars'],
  getSummary() {
    const self = this;
    return this.hobbies.map(function(hobby) {
        return `Hobby of ${self.name}: ${hobby}`;
    });
  }
}

// ES6
const person = {
  name: 'Homer',
  hobbies: ['beer', 'tv', 'cars'],
  getSummary() {
    return this.hobbies.map(hobby => `Hobby of ${this.name}: ${hobby}`);
  }
}

So this is it for ES6 fat-arrow functions. As you can see, they are great for increasing legibility of the code, reducing boilerplate, and in scenarios where we want to retain this binding of function's enclosing lexical scoping.