ES6 introduced a new syntax for functions, the so-called Arrow Functions. They are more concise and usually a better way of describing functions. Let’s see how they work:
By default the arrow function is anonymous, so you need to assign it to a variable if you want to call it later. The same could be done using the
Cool! But why should I use it? For starters, it looks better, doesn’t it? Take a look at how my code looks before and after using arrow functions.
Looks a lot better now! Take a good look and you’ll notice that I no longer need to use the
return keyword. If you omit the brackets, the value is automatically returned! This is particularly useful when you use inline functions, or when passing callbacks.
If you omit the brackets, the value is automatically returned!
What about Closures?
OK, so you agree that the code looks cleaner. But that’s not enough to convince you to start using the arrow function syntax. Well, there’s a hidden benefit to this: it solves some closure problems!
A closure is the combination of a function and the lexical environment within which that function was declared.
Let’s create a talking dog that barks his own name! Oh the wonders of coding…
Ok, so now if we run the code above we get a nice response:
rex.bark() // 'Woof, my name is Rex'
But in the process of training your now world famous talking dog you want to teach him the
sitAndBark method, where he is only allowed to bark after one second. And… it doesn’t work.
rex.sitAndBark() // 'Woof, my name is '
What happened? Here we have closures doing their work. The
setTimeout argument function has its own lexical scope, meaning you are trying to access
this.name inside this new function now. Since it does not have a
name property, the value resolves to
How do we solve it? Well, we could use the
bind method to bind the class lexical scope to the argument function.
this.name works as we intended.
rex.sitAndBark() // 'Woof, my name is Rex'
Let’s introduce the arrow function syntax now!
And it works!
rex.sitAndBark() // 'Woof, my name is Rex'
What happened here? This works because arrow functions don’t have a separate
this . When trying to access
this inside an arrow function, since they don’t have their own lexical scope defined, it’ll fall back to the previous scope, which is the class scope in this case. A much better approach than having to bind all your functions!
Arrow functions don’t have a separate
this. When trying to access
thisinside an arrow function it’ll fall back to the previous scope, since they don’t have their own lexical scope defined.
Now that you are convinced, you are probably writing your own arrow functions while reading this. You’ll start using them everywhere and soon your code will look cleaner than ever. But…
DON’T USE ARROW FUNCTIONS EVERYWHERE!
Wait, why? They’re cleaner, and they solved all your closure problems. Didn’t they? Well, not all of them…
If you read the first paragraph of this article you’ll see that I said arrow functions are more concise and usually a better way of describing functions. If you don’t know what you’re doing you’ll do more harm than good. Take a good look at this example:
In the example above there’s a declaration for a
Array.prototype.first method, that returns the first element in the array. If you mindlessly use arrow functions without understanding closures, you’ll end up with something like this.
The second example doesn’t work, and could lead to unpredictable results. The syntax is correct, and in theory both examples do the same thing: return the element in the first position. But since arrow functions don’t have their own lexical scope defined,
this will reference whatever is the previous scope which could be anything from another function to the global scope or
The first example works because using the
function keyword assigns the proper lexical scope to the function, and
this will reference the array itself correctly.
What’s the conclusion?
Arrow functions are here to stay. They make functional programming code (or any code actually) look cleaner. They solve closure problems with readable and minimal syntax. They rescue puppies from burning buildings. In short, they’re awesome.
Just one bit of advice:
When using arrow functions mind the correct use of closures, and always have in mind the scope you are working with.
Even if you always use arrow functions because they look better, never forget that they don’t solve all your problems. Sometimes going back to the basics is the better solution.