Arrow Functions and ‘this’ in ES6

The nuts and bolts of binding in JavaScript

Joe Cardillo
3 min readJun 13, 2018
Photo by Park Troopers on Unsplash

In a previous post I talked about the benefits of arrow functions. But it’s also important to understand when and why we’d want to use an arrow function vs. a regular function.

In order to make this distinction it’s important to understand how ‘this’ does not get rebound in an arrow function.

‘this’ gif

To help understand this, I’ve created a short animation (based on Wes Bos’s “ES6 for Everyone” course) which contains a function within a function. To start, let’s look at the first function.

const box = document.querySelector('.box');
box.addEventListener('click', function() {
console.log(this);
});

When the box is clicked, what does ‘this’ return in the console?

<div class="box">...</div>

In other words, ‘this’ is bound to the element the event is attached to. If you go backwards from ‘this’: function > ‘click’ > EventListener > box class > div.

Nice. Now let’s change it to an arrow function and see what it binds ‘this’ to:

box.addEventListener('click', () => {
console.log(this);
});
// When the box is clicked it returns:Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

The entire window? What’s going on here?

As we saw, using the regular function, it calls an event on the <div> with a class of ‘box.’

With the arrow function, however, ‘this’ is bound to the window element and does not get rebound within the function.

To put it further into perspective, let’s see what happens if we nest a regular function within the first function, then log ‘this’ to the console:

const box = document.querySelector('.box');
box.addEventListener('click', function() {
console.log(`First this:`);
console.log(this);
setTimeout(function() {
console.log(`Second this:`);
console.log(this);
}, 500);
});
// Returns in console:
First this:
<div class=​"box">​…​</div>​
Second this:
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

Why is the second ‘this’ returning the entire window if it’s within a function?

It’s because we’ve entered a new function, and this new function has not been bound to anything yet.

Therefore, the binding of ‘this’ will default to the window.

Again, if I simply call ‘this’ in the console I get:

Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

If we change the second function to an arrow function, ‘this’ now inherits its binding from the parent function, which in our case is bound to the <div> element with the class of ‘box.’

const box = document.querySelector('.box');
box.addEventListener('click', function() {
console.log(`First this:`);
console.log(this);
setTimeout(() => {
console.log(`Second this:`);
console.log(this);
}, 500);
});
// In the console:
First this:
<div class=​"box">​…​</div>​
Second this:
<div class=​"box">​…​</div>​

Recap

When deciding whether to use an arrow function vs. a regular function, think about context and what you want 'this' to be bound to.'This' will bind to the window by default. When using 'this' in a regular function, 'this' will be rebound to whatever the function is bound to.When using 'this' in an arrow function, the binding of 'this' will default to the parent scope!

--

--

Joe Cardillo
Joe Cardillo

Written by Joe Cardillo

Solutions Architect at Akamai Cloud

Responses (3)