Arrow Functions in JavaScript

Sydney Garay
6 min readJun 25, 2018

--

If you’re learning JavaScript, you’ve probably encountered arrow functions, which use arrow notation (=>) to concisely define a function. They can be very handy but it is important to know when to use them, and when not to use them. Take a look at an example of an arrow function below:

In the above example, an array of names is defined and we are trying to find and log the name equal to “Waldo” using a the .find method. The .find method accepts an argument of a callback function, and here we are passing in an arrow function. The left side of the function is an individual element of the array which we are iterating over, and the right side is the condition upon which we want to return the element. When the condition first evaluates to true, the element that triggered the true statement will be returned as we see above. We will explore the why arrow functions are commonly used as callback functions for iterator methods such as .find, .map, and more.

Benefits of using arrow functions:

  • They have shorter syntax than function expressions
  • They have implicit return statements
  • They retain scope of the method declared in when used as inner functions
Arrow functions shorten the syntax of callback functions for iterator methods.

In the above example, we can observe both of these benefits to using arrow functions. We wrote two expressions to log an array of the lengths of our cat names. The first uses a simple function expression, and the second an arrow function. The syntax of the second expression is shorter and more clear with the implementation of our arrow function. We can also observe that we did not have to explicitly write “return” in our arrow function as we did in our function expression. If we had left “return” out of our function expression we would see this:

The callback function returns undefined because we did not specify what to return.

This is because a function in JavaScript will return undefined unless we tell it to return something — that is, regular function expressions use explicit returns. The callback function in line 11 needs to return something for .map to add it to the new array.

Implicit vs. explicit returns with arrow functions:

The arrow function in line 8 is in fact returning the lengths of the cat names, even though we did not explicitly write “return.” This is because arrow functions use implicit returns when written without curly brackets.

Return is implicit for arrow functions without curly brackets.
Return is explicit for arrow functions with curly brackets.

The two arrow functions above behave exactly the same way but use slightly different syntax: use of curly bracket notation in an arrow function means that return will have to be explicit. We can see that the notation in line 8 is more clear and concise, however, we may choose to write an arrow function with curly brackets if we wanted to add more lines of code before the return such as a debugger, like so:

Using curly brackets with an arrow function allows us to add more lines of code before the return.

Note that if you write an arrow function with curly brackets but do not return anything, the function will return undefined (just like a regular function as we saw in line 11).

We are missing an explicit return with this arrow function using curly brackets.

Arguments for arrow functions:

When there is just one argument, we can write an arrow function with the arguments on the left side of the arrow, either enclosed or not enclosed by parentheses. The example below shows the many ways we could write the same arrow function:

When there are multiple arguments, however, we need to enclose them in parentheses:

With more than one argument, parentheses are required.

With no arguments, we can use empty parentheses instead:

The arrow function will be invoked for every element in cats, but no argument is passed in.

Arrow functions and “this”:

Unlike a regular function expression, if we use an arrow function inside another function, the arrow function retains the scope of the method it was declared in.

In the above example, a function expression is invoked from another function, so “this” is global. The function expression rebinds the value of “this” to the global context.

Writing “.bind(this)” after our inner function expression binds the context of that function to the context of the method it was declared in.

If we instead use an arrow function for the inner function, we do not have to bind the context of that function (and thus, the value of “this”), because arrow functions retain the scope of the method they were declared in. That is, arrow functions do not rebind the value of “this” because they do not have their own “this.”

Constraints of using arrow functions:

  • They are not suited for object-methods
  • They cannot be used as constructors
  • They are anonymous

Since arrow functions do not rebind the value of “this,” when using an arrow function as an object method, “this” will point to the parent scope. Thus, we cannot decrement fatCat1's weight using “this” in an arrow function method.

Instead, we should use regular function expressions for object methods that utilize “this.” We see below that using by a function expression instead, “this” is bound to the scope of fatCat2.

It is also important to note that because arrow functions do not rebind “this,” they cannot be used as constructors. Using an arrow function as a constructor will result in the error shown below:

Finally, since arrow functions are anonymous, they can be harder to debug. We can, however, assign them to a variable for more clarity in our error messages, as we saw in the above example.

Conclusion:

Arrow functions are a very useful tool for specific situations: they are best suited for non-method functions, any situation that requires “this” to be bound to the context rather than the function itself, and callback functions for iterator methods. However, they are anonymous, poorly suited for object methods, and cannot be used as constructors.

--

--