This Keyword In Javascript

Learn about the infamous 'this' keyword of javascript

In JavaScript, the this keyword refers to an object. It is a special keyword that is created for every execution context of every function. It takes the value of the "owner" of the function in which the this keyword is used

The value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called, which implies that this is NOT static. It even behaves differently if used in strict and non-strict modes. As a beginner it is confusing but this blog will help you to clear your foggy mind.

In this blog, we will see the implementation of this keyword in 3 contexts.

  • this in method call of an object
  • this in case of a simple function call
  • this in case of an arrow function

TLDR

  • In the case of a simple function call, this key is undefined when used in strict mode, and the window object when used in non-strict mode.
  • In the case of calling a method, this is bound to the object which is calling the method instead of the object in which we wrote the method.
  • In the case of the arrow function, they don't have their own this keyword, instead, they inherit the one from the parent scope, which is called "lexical scoping".

this in method call of an object

this keyword points to the global/window object when used outside a function, in the global scope.

console.log(this) //Window { window: Window, self: Window, document: HTMLDocument, name: "", location: Location, … }

When we call a method of an object, this keyword inside the method will be that object which is calling the method. It will NOT point to the object in which we wrote the method.

To give you an example:-

const user = {
  firstName:"Jon",
  lastName:"Doe",
  getFullName:function(){
   console.log(`${this.firstName} ${this.lastName}`) //Jon Doe
   console.log(this) //Object { firstName: "Jon", lastName: "Doe", getFullName: ƒ }
  }
}
user.getFullName()

As you see here, this keyword points to the user object because it is the user object which is calling the method (getFullName)

However, the result would not be the same if the method is called from another object.

const user = {
  firstName:"Jon",
  lastName:"Doe",
  getFullName:function(){
 console.log(`${this.firstName} ${this.lastName}`) //MS Dhoni
  console.log(this) //Object { firstName: "MS", lastName: "Dhoni", getFullName: ƒ }
  }
}

const newUser = {
  firstName:"MS",
  lastName:"Dhoni",
}
newUser.getFullName = user.getFullName
newUser.getFullName()

In this example:-

  • We have a new object, newUser.
  • We are borrowing getFullName method of the user to newUser

This results in, this keyword getting bound to the newUser, the object which is calling the method.

this in the case of a simple function call

this keyword performs differently in the case of simple function call when used with strict mode and without strict mode.

When used with strict mode

this keyword of a function is undefined when a function is simply called in strict mode. It is undefined because this keyword has no owner to say.

const calculateAge=function (birthyear){
  "use strict"
  console.log(this) //undefined
  console.log(2022-birthyear) //23
}
calculateAge(1999)

When used without strict mode

this keyword of a function is pointed to the global window object when a function is simply called in non-strict mode. Javascript loosely binds this to the window object when strict mode is not used.

const calculateAge=function (birthyear){
  console.log(this)//Window { window: Window, self: Window, document: HTMLDocument, name: "", location: Location, … }
  console.log(2022-birthyear) //23
}
calculateAge(1999)

this in case of an arrow function

Arrow functions do not have their own this keyword, instead, they inherit the one from the parent scope, which is called "lexical scoping".

Let's see it in an example

const calculateAge= (birthyear)=>{
  console.log(this) //Window { window: Window, self: Window, document: HTMLDocument, name: "", location: Location, … }
  console.log(2022-birthyear) //23
}
calculateAge(1999)

Here this is bonded to the global window object because the arrow functions don't have this keyword of their own they inherit the one from their parent scope which is the window object in this case.

Now let's see another example

const user = {
  firstName:"Jon",
  lastName:"Doe",
  getFullName:()=>{
   console.log(`${this.firstName} ${this.lastName}`) //undefined undefined
   console.log(this) //Window { window: Window, self: Window, document: HTMLDocument, name: "", location: Location, … }
  }
}
user.getFullName()

Here we see that this keyword is bound to the window object because, unlike regular functions, they don't have this keyword of their own they inherit it from their parent scope. Which is a window object not a user object. This is the reason why we can't access the properties of the user object using this keyword from an arrow function.

To make this work we have to use the arrow function in a way where the parent's scope is the user object.

const user = {
  firstName: "Jon",
  lastName: "Doe",
  getFullName: function() {
    const getFullNameArrow = () => {
      console.log(this) //Object { firstName: "Jon", lastName: "Doe", getFullName: ƒ }
      console.log(`${this.firstName} ${this.lastName}`) //Jon Doe
    }
    getFullNameArrow();
  }
}
user.getFullName()

Now you know this keyword in depth.