Arrow Functions
Explore the syntax and behavior of ES6 arrow functions, including implicit returns, handling of the this keyword, and differences from traditional functions. Understand when to use arrow functions effectively and how they impact scope and arguments in your JavaScript code.
What is an arrow function?
ES6 introduced fat arrows (=>) as a way to declare functions.
This is how we would normally declare a function in ES5:
The new syntax with a fat arrow looks like this:
We can go further if we only have one parameter. We can drop the parentheses and write:
If we have no parameters at all, we need to write empty parenthesis like this:
Implicitly return
With arrow functions, we can skip the explicit return and return like this:
Look at a side by side comparison with an old ES5 Function:
Both functions achieve the same result, but the new syntax allows you to be more concise. Beware! Readability is more important than conciseness so you might want to write your function like this if you are working in a team and not everybody is totally up-to-date with ES6.
Let’s say we want to implicitly return an object literal. We’d do it like this:
In this example, we’re using the map function to iterate over the array runners. The first argument is the current item in the array, and the i is the index of it. For each item in the array we are then adding into results an Object containing the properties name, race, and place.
To tell JavaScript what’s inside the curly braces is an object literal we want to implicitly return, so we need to wrap everything inside parentheses. Writing race or race: race is the same.
Arrow functions are anonymous
As you can see from the previous examples, arrow functions are anonymous.
If we want to have a name to reference them we can bind them to a variable:
Arrow function and the this keyword
You need to be careful when using arrow functions in conjunction with the this keyword, as they behave differently from normal functions.
When you use an arrow function, the this keyword is inherited from the parent scope.
This can be useful in cases like this one:
The problem in this case is that the first this is bound to the const box but the second one, inside the setTimeout, will be set to the Window object, throwing this error:
Uncaught TypeError: cannot read property "toggle" of undefined
You won’t be able to see this error in the Educative environment.
Since we know that arrow functions inherit the value of this from the parent scope, we can re-write our function like this:
Here, the second this will inherit from its parent, and will be set to the const box.
Running the example code, you should see our div turning red for just half a second.
When you should avoid arrow functions
Using what we know about the inheritance of the this keyword we can define some instances where you should not use arrow functions.
The next two examples show when to be careful using this inside of arrows.
Example 1
Example 2
Another difference between arrow functions and normal functions is the access to the arguments object.
The arguments object is an array-like object that we can access from inside functions and contains the values of the arguments passed to that function.
A quick example:
As you can see we accessed the first argument using an array notation arguments[0].
Similarly to what we saw with the this keyword, arrow functions inherit the value of the arguments object from their parent scope.
Let’s have a look at this example with our previous list of runners:
This code will return:
ReferenceError: arguments is not defined
To access all the arguments passed to the function we can either use the old function notation or the spread syntax (which we will discuss more in the lesson: Spread Operator and Rest Parameters)
Remember that arguments is just a keyword, it’s not a variable name.
Example with arrow function:
Example with function: