Photo by Simon Abrams on Unsplash

When I first started learning JavaScript, it took me some time to understand the this keyword in JavaScript and be able to quickly identify which object does the this keyword point to. I found that the hardest thing about understanding the this keyword is that you usually forget the different cases and situations that you have read about or watched people explain during one or more of the JavaScript courses or resources that you study from. After introducing the arrow functions in ES6, things got more confusing too because arrow functions deal with the this keyword in a different way. I wanted to write this article to state what I have learned and try to explain it in a way that could help anyone who is learning JavaScript and having difficulty understanding the this keyword as I did before.

As you may know, the environment (or the scope) in which any JavaScript line is being executed is called “The Execution Context”. The Javascript runtime maintains a stack of these execution contexts and the execution context present at the top of this stack is currently being executed. The object that this variable refers to changes every time when the execution context is changed.

By default, the execution context is global which means that if a code is being executed as part of a simple function call then the this variable will refer to the global object. In the case of a browser, the global object is the window object. In a Node.js environment, for example, a special object global will be the value of this .

For example, try the following simple function call:

function foo () {

console.log("Simple function call");

console.log(this === window);

} foo();

By calling foo() , we will get this output:

“Simple function call”

true

This proves that this here refers to the global object, which is the window object in our case.

Note that, if strict mode is enabled for any function then the value of this will be undefined because in strict mode global object refers to undefined in place of the window object.

Let’s try the following example:

function foo () {

'use strict';

console.log("Simple function call");

console.log(this === window);

} foo();

Our output, in this case, will be:

“Simple function call”

false

Let’s imagine now that we have the following constructor function:

function Person(first_name, last_name) {

this.first_name = first_name;

this.last_name = last_name;



this.displayName = function() {

console.log(`Name: ${this.first_name} ${this.last_name}`);

};

}

Let’s create some Person instances:

let john = new Person('John', 'Reid');

john.displayName();

If we try that in our console, we should get the following output:

"Name: John Reid"

What happened here? When we call new on Person , JavaScript will create a new object inside the Person function and save it as this . Then, the first_name , last_name and displayName properties will be added on the newly created this object. I used this awesome JavaScript visualizer tool from Tyler McGinnis to see how this actually looks like behind the scenes. This is what I got:

You will notice that we have a this object created inside the execution context of Person and that this object has the three properties first_name , last_name and displayName . This tool animates the steps happening behind the scenes in an interesting way that will help you understand how the this object is created and filled.

We have now discussed two common cases related to the this keyword binding. There’s one more case that I wanted to mention and that could be a little confusing too. Imagine that we have this function:

function simpleFunction () {

console.log("Simple function call")

console.log(this === window);

}

We now know that if we do a simple function call like the following, the this keyword will refer to the global object, in our case, it’s the window object. Let’s do that:

simpleFunction();

Indeed, we get this in as our output:

“Simple function call” true

Let’s create a simple user object like the following:

let user = {

count: 10,

simpleFunction: simpleFunction,

anotherFunction: function() {

console.log(this === window);

}

}

Now, we have a simpleFunction property referring to our simpleFunction function. We have also added another property as a method called anotherFunction .

If we call user.simpleFunction() , we will get this in our console’s output:

“Simple function call”

false

Why did that happen? Because simpleFunction() is now a property of the user object, then the this keyword will refer to the user object and not the global object in this case.

If we call user.anotherFunction() now, we should expect the same thing too. Our this keyword will refer to the user object. So, console.log(this === window); should return false and we should get this output in our console:

false

Let’s discuss one more case. What will happen if we do something like the following?

let myFunction = user.anotherFunction; myFunction();

If you try this, you should get this output:

true

But why did this happen? In this case, we do a simple function call. As we already know by now, if a method is invoked as a simple function, then the this keyword will refer to the global object which is in our case equals to the window object, and hence console.log(this === window); will print true .

Let’s see another example:

var john = {

name: 'john',

yearOfBirth: 1990,

calculateAge: function() {

console.log(this);

console.log(2016 - this.yearOfBirth); function innerFunction() {

console.log(this);

}

innerFunction();

}

}

What will happen now if we call john.calculateAge() ? We should get something similar to this:

{name: "john", yearOfBirth: 1990, calculateAge: ƒ}

26

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