“this” in Javascript

Lakshan Bandara
3 min readJan 29, 2022

Here we are going to look at the behavior of the “this” keyword in different javascript contexts.

As mentioned in the topic description, “this” keyword refer to different objects based on the context and how the invocation happens.

1. traditional functions ( functions start with function keyword):

function myFunction() {
console.log(this === global)
};
myFunction();// prints true

Since the function is called in global scope, here “this” refers to the global object (window object in browser environment).

2. traditional function with “new” keyword

function myFunction() {
console.log(this)
}
const test = new myFunction()
test;
// prints: myFunction {}

With the usage of “new” keyword, it will call the constructor of myFunction and create a new instance of myFunction. Inside this new instance, “this” keyword refers to the object itself.

3. traditional function inside an object

method 01:

const obj = {
myFunction() {
console.log(this === global);
}
};
const test = obj.myFunction;
test();
// prints: true

method 02:

const obj = {
myFunction() {
console.log(this === global);
}
};
obj.myFunction();// prints: false

In method number 01, we extract the function from the object and call the function at the global level. Then the “this” keyword refers to the global object.

In method number 02, we call the function when it remains inside the object. Then the “this” keyword refers to the object itself.

4. nested functions

const obj = {
myFunction() {
console.log(this)
},
nestedFunction() {
function innerFunction() {
console.log(this);
}
return innerFunction()
}

}
obj.nestedFunction();
prints: global object

In this example, we are calling the “nestedFunction” inside the object but “this” still refers to the global object. Why?????

Even though we called the nested function inside the object scope, the “innerFunction” invocation happens directly. So the “this” keyword inside the “innerFunction” refers to the global object.

important: How the function is invoked matters!!!!!!!!!!.

Common misuses of “this”

number 01:

function Bottle() {
return this;
}
const bottle1 = Bottle();
const bottle2 = Bottle();
bottle1.waterLevel = 100;
bottle2.waterLevel = 200;
console.log(bottle1.waterLevel);
console.log(bottle2.waterLevel);
prints : 200
200

The bottle1 and bottle2 objects both refer to the same global object and setting up the waterLevel attribute to bottle1 one will add a new entry to the global object. That value will get overwritten while setting the waterLevel for the bottle2.

This can be fixed using the “new” keyword:

function Bottle() {
return this;
}
const bottle1 = new Bottle();
const bottle2 = new Bottle();
bottle1.waterLevel = 100;
bottle2.waterLevel = 200;
console.log(bottle1.waterLevel);
console.log(bottle2.waterLevel);
prints: 100
200

“new” keyword will create two separate instances of object type Bottle. And “this” will refer to the instance itself.

number 02:

const bottle = {
waterLevel: 100,
refillWater() {
setTimeout(function (){
console.log("refilled, new amount is : ", this.waterLevel+100)
}, 1000)
}
}
bottle.refillWater();prints: refilled, new amount is : NaN

When we are using inbuilt functions like setTimeout, this is a common mistake many of us do. The callback function which passes for the set timeout gets invoked directly and the “this” keyword will refer to the global object. We haven’t set an attribute called waterLevel inside the global object. So the result will be NaN.

We can resolve this by using a small hack ;)

const bottle = {
waterLevel: 100,
refillWater() {
_this = this;
setTimeout(function (){
console.log("refilled, new amount is : ", _this.waterLevel +100);
}, 1000)
}
}
bottle.refillWater();prints: refilled, new amount is : 200

The usage of arrow functions will also help to mitigate these kinds of issues. Let’s have look at how it happens in the next article on arrow functions!

--

--