Is "this" tricky in Javascript? No way!๐Ÿ˜Ž

Is "this" tricky in Javascript? No way!๐Ÿ˜Ž

Understanding the "this" keyword in JavaScript: Explained with Examples

ยท

4 min read

In JavaScript, the this keyword is a special identifier that refers to the context in which a function is executed. It plays a crucial role in determining how functions behave and which object they belong to. However, the behaviour of this can be confusing for many developers.

Simply, this points to the context in which it is used. We will explore various examples of this keyword and understand how it points to the context in which it is used. We will also see examples where this can be explicitly bound to any specific object or a function call.

Global Context: Default Binding

When this is used outside of any function, it refers to the global object. In a web browser environment, the global object is usually the window object. Let's consider the following example:

console.log(this); // Output: Window

In this case, this points to the window object because the code is executed in the global context. Pointing to the window object specifies that this will have access to all the properties of the window object. For example, as window object has setTimeout property, so here we can access it through this.setTimeout as well. It is that simple!

Object Method: Implicit Binding

When a function is called as a method of an object, this refers to the object itself. This behavior is known as implicit binding. It's called Implicit because it is assigned by the javascript engine during the runtime. Let's look at an example:

const person = {
  name: 'Om',
  greet: function() {
    console.log(`Hello, my name is ${this.name}.`);
  }
};

person.greet(); // Output: Hello, my name is Om.

In this example, this inside the greet() method refers to the person object. It allows us to access the name property of the person object using this.name. Here, this will only have access to the properties defined in the person object.

Event Handlers: DOM Binding

When an event handler is invoked, this refers to the element that triggered the event. Let's consider an HTML button element with an event handler function:

<button onclick="console.log(this)">Click me</button>

In this case, when the button is clicked, this inside the event handler function refers to the button element itself. It provides access to the element's properties and methods.

Constructor Functions: New Binding

When a function is used as a constructor with the new keyword, this refers to the newly created object. Constructor functions are used to create multiple objects with the same properties and methods. Here's an example:

function Person(name) {
  this.name = name;
}
// can also be defined with class keyword 
/*
class Person {
   constructor(name) {
     this.name = name;
   }       
}*/
const person = new Person('Om');
console.log(person.name); // Output: Om

In this example, the Person function acts as a constructor to create a new Person object. Inside the constructor, this refers to the newly created object (john), allowing us to set the name property.

Explicit Binding: Call, Apply, and Bind

JavaScript provides three methods - call(), apply(), and bind() - that allows us to explicitly specify the value of this within a function. Let's explore each of them with an example:

Note - To understand these functions in detail you can check here.

function greet() {
  console.log(`Hello, ${this.name}!`);
}

const person1 = { name: 'Om' };
const person2 = { name: 'Apurva' };

greet.call(person1);  // Output: Hello, Om!
greet.call(person2);  // Output: Hello, Apurva!

greet.apply(person1); // Output: Hello, Om!
greet.apply(person2); // Output: Hello, Apurva!

const greetPerson1 = greet.bind(person1);
const greetPerson2 = greet.bind(person2);
greetPerson1();       // Output: Hello, Om!
greetPerson2();       // Output: Hello, Apurva!

In the above example, we define a greet() function that logs a greeting message. By using call(), apply(), and bind(), we explicitly set this to the person object. This allows us to access the name property of person within the greet() function.

Arrow Functions: Lexical Binding

Arrow functions do not bind their own this value. Instead, they inherit the this value from the enclosing context.

const person = {
  name: "Om",
  greet: function() {
    setTimeout(() => {
      console.log(`Hello, my name is ${this.name}`);
    }, 1000);
  }
};

person.greet(); // Output: Hello, my name is Om

Here the callback function (an arrow function) in setTimeout will refer to the context of the object method greet. As we know the object method will refer to the person object in which it is defined (this we have already seen in the Object Method section), and the callback will also refer to person object.

These examples demonstrate how the context of this can vary depending on the way a function is called or the surrounding code. Understanding the different contexts of this is crucial for writing correct and maintainable JavaScript code.

Did you find this article valuable?

Support Code Craft - Fun With Javascript by becoming a sponsor. Any amount is appreciated!

ย