All Points Bulletin Board: What Are Arrow Functions?
By: Ashley Bergsma
Tags: Functions In Javascript, Arrow Functions, JavaScript, Web Development

Question: What are Arrow Functions?

Short Answer: Basically, shortened function expressions.

Arrow functions were introduced before I became acquainted with JavaScript. I wasn’t sure when I was seeing them, where to use them, and why I would even want to. In the beginning I didn’t even recognize them as functions — they don’t have the trademark keywords we usually see, and some don’t even require parenthesis or brackets.

const multiply = (a, b) => a * b;

Arrow functions don’t include the keyword function and if the code block is only one statement long, like the example above, the return keyword can be omitted. Furthermore, if only one parameter is passed in, the parentheses wrapping it can be left out.

const double = n => n * 2;

But that’s not the whole story. Function expressions and arrow functions (also known as “fat arrows”) can behave very differently, looking under the hood will explain why.

Long Answer:

To really break down what an arrow function is, I started by exploring the other ways functions are declared in JavaScript. Namely, function declaration and function expression.

A function created using function declaration is also known as a named function. These functions are hoisted to the top of their scope, and are called by their name. Named Functions effectively store functions until we need them.

// Function Declaration / Function Statement / Named Function function multiplyOrDivide(a, b){

if (a % 2 === 0){

return a * b

} else {

return a / b

}

};

On the other hand, a function created using function expression is known as an anonymous function. Anonymous functions are often stored in a variable, which is how we’ll eventually call them.

You’ll see functions created this way used as IIFEs — Immediately Invoked Function Expressions. That’s a separate blog post though.

// Function Expression / Anonymous Function const multiply = function(a, b){return a * b}; console.log(multiply(5, 10));

// -> 50

The main difference between these two is the function name and **hoisting. Function declarations are hoisted, function expressions are not.

**Note: In short, hoisting refers to the JavaScript compilers way of reading code — variable declarations are ‘lifted’ to the top of their scope and they can be called before they appear in the code. The compiler does this to preemptively create space in memory, but it can create bugs if you don’t know what’s going on. (Read more about hoisting Here)

Arrow Functions: Use Cases and Gotchas

Arrow functions were introduced in ES6, in large part to reduce confusion surround the this keyword. When writing code using Promises and Callbacks, for example, the resulting code can be a maze of return and function keywords, and this can be hard to keep track of.

Use Case: Using an arrow function provides lexical this

In ES5 the complexities related to this were worked around by creating closures, or using the (performatively slow) .bind() method. Arrow functions are a salve for this— they retain the scope of the caller inside the function. Let’s look at an example.

// Function Expression / Anonymous Function API.prototype.get = function(resource) { var self = this; // closure created to bind this return new Promise(function(resolve, reject) {

http.get(self.uri + resource, function(data) {

resolve(data);

});

});

};

This example was pulled from an article by Jack Pennell, where he cites Jack Franklin as the provider. You can read the whole article here.

It’s a good example to visualize what we’re talking about. Going into the function we immediately have to bind this and then site it in the get method. Using an arrow function we don’t have to do this extra step.

// Arrow Function / Fat Arrow Function API.prototype.get = function(resource) {

return new Promise((resolve, reject) => {

http.get(this.uri + resource, function(data) {

resolve(data);

});

});

};

In the arrow function (that retains the scope of its caller) this is already bound. In fact we cannot change its value. Methods like call , apply , and bind will not work.

Unlike other function types, arrow functions have no prototype property — they’re more akin to a method (or an internal function) in this way. If we needed the uri in this example to be dynamic, we would not be able to use an arrow function.

Use Case: Easier to read array manipulations

ES6 came with more than just array functions (although arrow functions have been the most used addition), array methods like the very popular map function were also introduced. Using arrow functions in methods to manipulate and read arrays can arguably make them easier to read.

// Function Expression / Anonymous Function const groceryList = [

{name: 'bananas', type: 'fruit'},

{name: 'broccoli', type: 'vegetable'},

{name: 'chicken', type: 'poultry'},

{name: 'apples', type: 'fruit'}

]; const types = groceryList.map(function(item) {

return item.type;

});

Now let’s use an arrow function:

// Arrow Function const groceryList = [

{name: 'bananas', type: 'fruit'},

{name: 'broccoli', type: 'vegetable'},

{name: 'chicken', type: 'poultry'},

{name: 'apples', type: 'fruit'}

]; const types = groceryList.map(item => {

return item.type;

});

We can simplify the function even further: