Mastering the JavaScript This Keyword: Your Ultimate Guide

Introduction

In JavaScript, the JavaScript this keyword refers to an object, but the specific object it references depends on how and where the function is called. This behavior changes depending on whether the function is a regular function or an arrow function. In this article, we’ll explore how the value of this varies.

Before learning about the ‘this’ keyword, let’s understand what are:

  • Regular Function
  • Arrow Function
  • Method
  • Global Context

Regular Function

A standard JavaScript function declared using the function keyword (e.g., function myFunction() {}).

//Syntax
function method_name(){
  //Define Functionality
}

//Example
function vehicle(){
  console.log("The vehicle is running at the speed of 400km/h");
}

You can also write a function like below:

//Syntax
let method_name = function (){
 //Define functionality
}

//Example
let car = function(){
  console.log("The car is white");
}

This is a regular function. It can have parameters as well as it can return something (We will discuss them in another blog).

Arrow Function

A function defined using the arrow syntax (e.g., () => {}).

//Syntax
()=>{
  //Define functionality
}

Example:

()=>{
  console.log("This is arrow function");
}

We can assign this arrow function to a variable:-

function_name = ()=>{
  //Define functionality
}

Example:

run = ()=>{
  console.log("The vehicle is running");
}

An arrow function can have parameters and it can return something as well.

Method

A regular function that is declared within an object is considered a method. It is a property of an object. An arrow function is not considered a method even if it is declared within an object because of its behavior. (We will discuss it later in this blog).

let obj = {
  play(){
    console.log("play method within the object obj");
  }
}

The function play() is defined within the object obj, and since it is a regular function, so it is considered as a method.

We can also write an arrow function within an object.

let obj2 = {
  ()=>{
    console.log("Arrow Function"); //Arrow function within the object obj2
  }
}

Although the arrow function is defined inside the object obj2, it is not considered a method due to its behavior.

Global Context

When a function or an object is not defined in any object. That means the function or the object is directly defined in a global scope or global context.

function method_name(){
  //Define Functionality
}

Example:-

function vehicle(){
  console.log("The vehicle is running at the speed of 400km/h");
}

You can also write a function like below–>

let variable_name = function(){
  //Define functionality
}

Example:

let car = function(){
  console.log("The car is white");
}

These regular functions are not defined in any object. So, their context is global.

We can also write the arrow function directly into the global scope:

arrowFunction = () => {
    console.log("this is arrow function defined in global scope"); 
};

JavaScript this keyword in regular function

In regular functions, the value of this depends on how the function is called.

Let’s understand through some examples:

let vehicle = {
  speed:"400km/h",
  run(){
    console.log(`The vehicle is running at the speed of ${this.speed}`);
  }
}

By seeing this example, you can say that run is a method of the object ‘vehicle’ and the keyword ‘this’ in the vehicle should refer to the object ‘vehicle’. So, ‘this.speed’ should be equal to ‘400km/h’.

vehicle.run(); //The vehicle is running at the speed of 400km/h

Since we are calling ‘run()’ as a method of object ‘vehicle’, so this will refer to the object ‘vehicle’.

What would happen if I assign a function definition to another variable like below:

const another_function =  vehicle.run; //Assign definition of run to another variable 
 
another_function(); //The vehicle is running at the speed of undefined

We assigned the function definition in the variable ‘another-function’, and we are calling ‘another_function’ directly into the global context (Not as a method of an object). The ‘this’ keyword will refer to the global context. And, since the variable ‘speed’ is not defined directly into the global scope, ‘this.name’ will be undefined.

‘this’ In Arrow Function

Arrow functions do not have their own ‘this’. They inherit ‘this’ from the scope in which they are defined. This means that the value of ‘this’ inside an arrow function is the same as ‘this’ outside the arrow function. Let’s understand this with the help of an example–>

let truck = {
  speed:"400km/h",
  move : ()=>{
    console.log(`The truck is moving at the speed of ${this.speed}`);
  }
}

move() is defined directly into the object truck. What would happen if you do ‘truck.move()’:

truck.move();

It will give:

The truck is moving at the speed of undefined

The reason is that the keyword ‘this’ is referencing the global context. Why?

The answer is: The arrow function does not own this keyword, they inherit it from the surrounding context. In our example, the arrow function ‘move()’ inherits the keyword ‘this’ from its surrounding context which is the object truck. Some people might have doubts about this. They might think that the object ‘truck’ does not have ‘this’ keyword.

It should be considered that the keyword ‘this’ in the arrow function move() belongs to the surrounding context. In our example, the surrounding context of move() is the object ‘truck’ in which the arrow function is defined. And, since the object truck is defined in the global context, so, this will refer to the global context. In our global context, speed is not defined, so, ‘this.speed’ will be undefined.

‘this’ In Callback Function

Callback function can also be of two types, regular function or arrow function.

const student = {
    name: "Alice",
    grade: 10,
    courses: ["Math", "Science", "English"],

    study: function() {
        this.courses.forEach(function (course){  //here, Callback function is a regular function
               console.log(this.name,course); 
        })
    },
}

What would be the output of student.study() –>

student.study();

The Output will be--> 

undefined, 'Math'
undefined, 'Science'
undefined, 'English'

This is because the callback function inside the function study() does not inherit the value of ‘this’ from its surrounding context.

But, if I use an arrow function as a callback. See the below code:

const student = {
    name: "Alice",
    grade: 10,
    courses: ["Math", "Science", "English"],

    study: function() {
        this.courses.forEach((course)=>{
               console.log(this.name,course); 
        })
    },
}
student.study();

The Output will be: 
'Alice', 'Math'
'Alice', 'Science'
'Alice', 'English'

Here, ‘this.name’ is not giving undefined. The reason is that the keyword ‘this’ has the same value as the value of ‘this’ in the study function. Since, ‘this’ in the study() function refers to the object student. So, the keyword ‘this’ in the arrow function which is a callback function in the study function will refer to the object student.

You can refer to wschool.com website to learn more about this keyword: Click Here

‘this’ with bind() method

bind() binds ‘this’ keyword with a particular object. Let’s understand it with an example:

const student = {
    name: "Alice",
    grade: 10,
    courses: ["Math", "Science", "English"],

    study: function() {
        console.log(`The name of the student is ${this.name}`);
    },
}

The primary purpose of the bind() method is to create a new function where the this keyword is permanently bound to a specific object. This means that no matter how the new function is called, this will always refer to the object you specified. bind() does not modify the original function. Instead, it returns a new function with the this the value set as you specified.

const my_function =  student.study.bind(student);
my_function();

The ‘this’ keyword in my_function will always refer to the object ‘student’ because we have passed ‘student’ as an argument. The output for ‘my_function()’ will be:

The name of the student is Alice

It is completely different from the function that is not bound to any object.

const student = {
    name: "Alice",
    grade: 10,
    courses: ["Math", "Science", "English"],

    study: function() {
        console.log(`The name of the student is ${this.name}`);
    },
}
const another_function = student.study();
another_function();

We assigned function definition with the variable ‘another_function’. Now, if we call ‘another_function()’ in the global context, this. name will give ‘undefined’. Because the this keyword is not bound to any object other than the global context.

You can refer to the official documentation to understand more about bind() method: Click Here

Conclusion

Understanding the behavior of JavaScript this keyword is crucial for writing correct JavaScript code, especially when dealing with object-oriented programming and callbacks. Remember that the value of this depends on the context in which a function is called. Regular functions have a dynamic this, while arrow functions inherit this from their surrounding scope. Additionally, methods like bind(), call(), and apply() offer explicit control over the this value.

Do you want to learn productivity tips of VS Code: Click Here

Leave a Comment