ES5 functions vs. ES6 ‘fat arrow’ functions

With ES6 you now have another options for creating Javascript functions. You are probably familiar with the ES5 way of creating a function with the ‘function’ keyword.

function sayHi(greeting){     return greeting;}sayHi('Hello!');// 'Hello!'

Pretty easy, right? A function like this has a few syntactic characteristics that must be present in all functions declared this way. First, is the ‘function’ keyword. Next, parenthesis are needed whether you have arguments or not. Then inside the code block, which requires it’s own set of parenthesis, the ‘return’ keyword is needed so that the function knows what you want to get out if it.

Behind the scenes, the function I just created also has its own ‘this’ context which will become important later.

For just one function that doesn’t seem like much, but if you add up all of the functions you have or will write in your coding career then that becomes a lot of overhead.

Arrow functions in ES6 allow you to remove some of that syntax along with refining how to handle ‘this’.

Syntactically, the previous function can be reduced down to one line.

var sayHi = greeting => greetingsayHi('Hello!');// 'Hello!'

As you can see, the ‘function’ keyword is no longer necessary. By using the fat arrow syntax ( => ) ES6 knows you are using a function. There are a few other bits of syntax magic going on here as well.

If you have only one argument, you don’t need to wrap it in parentheses.

If the code block has only one expression in it, you can eliminate the curly braces around it.

If you do eliminate those curly braces then you can also throw out the ‘return’ keyword since you will now have an implicit return.

This is a lot cleaner syntax and a bit less typing. But is it worth it? There seems to be a lot of ‘magic’ going on behind the scenes here that someone seeing this for the first time might not be able to easily understand. The ‘function’ keyword does at least give a clue as to what this code is trying to accomplish. Yes, it is more typing, but it is also less cognitive load for the reader.

That is the syntax side of things, but what about that other thing I mentioned? The fact that creating a function with ‘function’ creates its own ‘this’ context. Arrow functions handle that differently and this is where they end up doing a lot for you.

Take the following example code:

var pets = {
names: ['Baron', 'Chief', 'Axel'],
owner: 'Jason',
description: function(){
return this.names.map(function(pet){
return `${this.owner} knows an awesome dog named ${pet}.`
});
}
};
pets.description()

Here I am taking an array of pet names and passing them to the .map() function and want to return another array of strings that say I am the owner of these pets. Looks all well and good except that when this code is run you will see an unexpected result.

Not a great boost for my ego there Javascript.

Calling ‘this.owner’ from within that function doesn’t work. Why? Because ‘this’ is referring to the function that called it which doesn’t know what ‘owner’ is. What needs to happen is that ‘this’ needs to refer to the ‘pets’ object, not the function. In ES5 there are a couple of ways around this.

First you could .bind() this to the function.

Defining ‘this’ with a .bind() method

Or, you could just pass along the ‘this’ context you want to use as an argument to the function.

Defining ‘this’ as an argument to the function.

Or you could even set the value of ‘this’ to a variable inside the first function and reference it in the second function

Defining ‘this’ by caching it in a variable.

All of those work just fine. But an arrow function does away with both of those and makes it so you don’t have to figure out what exactly ‘this’ means when calling it in a function.

Just refactor the first example to an arrow function and you get…

Arrow functions don’t redefine ‘this’.

How does this work? I like to think of it as fat arrow functions don’t have their own or don’t change the context of ‘this’. They leave it alone so that it stays the same as the context in which the function was created.

Honestly, I still have a hard time using arrow functions but that is probably more out of habit then anything else. Syntactically, they give your fingers a bit of a break and they help make using ‘this’ clearer. What about you? Have you moved over to using ES6 arrow functions in your code?