JavaScriptTutorials

JavaScript – Fat Arrow Functions

What is a fat arrow function? What’s up with that crazy syntax? Why use it instead of a good ‘ol fashion function () {} function? What advantages does a fat arrow function give a developer? What is happening in the world!?!?

This will be a topic to hopefully explain and clarify one of the most common technical questions front end developers are asked during an interview: “What is a fat arrow function and why use it?” I’ve been asked various iterations of this question in multiple interviews from multiple different companies. Suffice it to say, this is a good topic to know if you’re a JavaScript developer of any sort. So let’s get into it.

Let’s tackle the first question above: What is a fat arrow function?

In simple terms, a fat arrow function is simply another way to write a JavaScript function. That’s it. There are some functional differences between the fat arrow function and the regular JavaScript function, but we’ll get into that later. For now, just know that a fat arrow function is simply a function. It is an encapsulated block of code which can be declared, and then later (or immediately) invoked to run said block of code.

And what’s up with that crazy syntax?

I’ll admit the first time I saw a fat arrow function, I didn’t know what was going on. It was greatly confusing, and just seemed irritating I had to learn a new way to write a function. However, after learning how it worked, I was happy to be able to write functions without using the function keyword. I’m pretty lazy, so for me, the less typing the better, so I have come to love that crazy syntax which powers the fat arrow function.

Here is a regular, hopefully familiar, good ‘ol fashioned JavaScript function and two different ways to write one:

function myFn () {
// code here...
}

let myFn = function () {
// code here...
};

Now, the exact same thing, except written with the fat arrow function syntax:

let myFn = () => {
// code here...
};

All three of these examples can be invoked similarly like:

myFn();

Why use a fat arrow function instead of a good ‘ol fashioned function () {} function?

Besides the shorthand syntax and less verbosity, let’s talk about some of the technical reasons/advantages of using fat arrow functions over regular functions. The main advantage of a fat arrow function is the way it handles the this keyword. That is, this remains bound to its original context. Whereas, in the good ol’ fashioned function () {} function way, the this keyword can easily lose it’s context if you’re not careful. And this is an important advantage of the fat arrow function. Let’s look at some examples of what I mean here:

In this example, we will first create a constructor function, with an array of integers, an empty array, and a method “printEvens()” which will loop through the array of integers and push only the even values into the empty array “evenNums”. And finally, it will print the resulting evenNums array to the console.

function Evens() {
this.nums = [88, 89, 90, 91];
this.evenNums = [];

this.printEvens = function () {
this.nums.forEach(function (num) {
if (num % 2 === 0) {
this.evenNums.push(num);
}
});

console.log(this.evenNums);
}
}

let myInst = new Evens();
myInst.printEvens(); // We get a TypeError here

If you run this code, you should see a TypeError in the console – something like:

Uncaught TypeError: Cannot read property 'push' of undefined

Well, that’s weird. Why did we get an error instead of printing all the even numbers found in the numbers array? Blame it all on this!!! Looking at the error again, you can see that this.evenNumbers is undefined inside of the forEach() loop. Well, that sucks, apparently this is losing it’s original context when inside the loop. And it’s all because of the function inside of the loop. Even worse, this is magically being bound to the global window object. Try throwing some console.log(this)‘s inside and outside of the for loop and see what you get. Fat arrow functions can readily solve this. Let’s see an example:

function Evens() {
this.nums = [88, 89, 90, 91];
this.evenNums = [];

this.printEvens = function() {
this.nums.forEach((num) => {
if (num % 2 === 0) {
this.evenNums.push(num);
}
});

console.log(this.evenNums);
}
}

let fatArrowInst = new Evens();
fatArrowInst.printEvens(); // We see an array of even numbers!

Sweet! It worked! So let’s unpack this. What’s different between the two examples? Besides the name of the constructor function, the only other difference is the implementation of one fat arrow function within the for loop. Using this instead of a good ol’ fashioned function, we can keep the original context of this within the loop.


Bonus points

Shorthand syntax with fat arrow functions.

let fn = () => console.log('foo');
fn(); // 'foo'

//***********************************

let fn1 = () => {
return { foo: 1, bar: 2 };
};

let fn2 = () => fn1();

fn2(); // returns { foo: 1, bar: 2 }

IIFE’s (immediately invoked function expressions) – the fat arrow way.

Here is the good ol’ fashioned way:

(function () {
// some code here which will be immediately invoked...
}());

..and the fat arrow way:

(() => {
})(
/* a line of code here immediately invoked */,
/* another line of code here immediately invoked (don't forget the comma separating these two lines) */
);

One thought on “JavaScript – Fat Arrow Functions

Leave a Reply

Your email address will not be published. Required fields are marked *