JavaScript's 'this' Keyword: Understand How It Works Under Different Scenarios
Are you confused by the this
keyword in JavaScript? It confuses everyone in the beginning, so don’t worry about it. You’re not alone
The this
keyword is very commonly used inside functions and objects. Once you understand this
, you’ll realize that it’s much simpler than you think it is.
By the end of this article, you would have demystified this
for yourself. You’ll know what it is, what it does and how to use it.
So, what is this
?
Where the function is declared alters what this
means. It always refers to one object, usually the object in which the function operates. There five different ways where this
can take on new values. They are:
- A function in global scope
- A method of an object
- Function expression as method
- A simple function
- Arrow Functions
As you will see, the value of this
will change in different situations. But don't worry if you do not follow this on your first read. As you write more functions and objects. these concepts will become more familiar, and if this
is not returning the value you expected, this article will help you work out why.
A function in global scope
When a function is created at the top level of a program (that is, not inside another object or function), then it is in the global scope or global context.
The default object in this context is the window
object. So when this
is used inside a function in the global context, it refers to the window
object.
Below, this
is being used to return properties of the window
object.
function windowSize() { let width = this.innerWidth; let height = this.innerHeight; return [height, width]; }
Under the hood, the this
keyword is a reference to the object that the function is created inside.
All global variables also become properties of the window
object. So when a function is in the global context, you can access global variables using the window object, as well as its other properties.
Here, the showWidth()
function is in global scope, and this.width
refers to the width
variable:
Usually, you wouldn’t use this
in a global context anyway, so the value of this
here doesn’t really matter. Let’s move on to the next one.
A method of an object
When a function is defined inside an object, it becomes a method. In a method, this
refers to the containing object.
In the example below, the getArea()
method appears inside the shape
object, so this refers to the shape
object it is contained in.
Because the this
keyword here refers to the shape object, it would be the same as writing -
return shape.width * shape.height;
If you were creating several objects using an object constructor (and each shape had different dimensions), this would refer to the individual instance of the new object you are creating. When you called getArea()
, it would calculate the dimensions of that particular instance of the object.
Let’s move on to the next context.
Function expression as method
If a named function has been defined in global scope, and it is then used as a method of an object, this
refers to the object it is contained within.
The next example uses the same showWidth()
function expression as the one that we used earlier, but it is assigned as a method of an object.
The last but one line indicates that the showWidth()
function is used as a method of the shape
object. The method is given a different name: getWidth()
When the getWidth()
method is called, even though it uses the showWidth()
function, this
now refers to the shape
object, not the global context (and this.width
refers to the width
property of the shape
object). So it prints a value of 300
to the console.
A simple function
Simple functions are functions you know extremely well; like the one below. Anonymous functions written in the same form are also considered simple functions.
function getWidth() { //Get Width }
this
is always set to Window
in a simple function. The same is true even if you call a simple function in an object method.
function getWidth() { console.log(this); } const shape = { printThis() { getWidth(); }, }; getWidth(); // Window shape.printThis(); // Window
This is usually tricky for beginners. They expect this
to remain the same within object methods. I got caught in it too.
To see why, consider the following code. Here, a this.getWidth()
function is executed later within a setTimeout
function.
const shape = { printLater() { setTimeout(function () { this.getWidth(); // Error }, 1000); }, getWidth() { console.log("34.89"); }, };
Unfortunately, the code above results in an error. The error occurs because this
is set to Window
in the setTimeout
function. Window
does not have a getWidth
method.
One quick fix is to create a variable that stores the reference to the this
.
const shape = { printLater() { const self = this; setTimeout(function () { self.getWidth(); }, 1000); }, getWidth() { console.log("34.89"); }, };
A second way to fix this problem is to use the new ES6 arrow functions, which brings us to the next section.
Arrow Functions
this
in an arrow function is always the same as this
around it (in its immediate scope). So, if you use arrow functions within an object method, the this
context stays as the object, not Window
.
With arrow functions, the getWidth
example could be written in the following way:
const shape = { printLater() { setTimeout(() => self.getWidth(), 1000); }, getWidth() { console.log("34.89"); }, };
Summary
In this article, you learned about the five different contexts where this
takes on different values.
That’s all you need to know about this
. Just master the concepts taught in this article and you won’t ever get confused anymore.
Get my free, weekly JavaScript tutorials
Want to improve your JavaScript fluency?
Every week, I send a new full-length JavaScript article to thousands of developers. Learn about asynchronous programming, closures, and best practices — as well as general tips for software engineers.
Join today, and level up your JavaScript every Sunday!
Thank you, Taha, for your amazing newsletter. I’m really benefiting from the valuable insights and tips you share.