What is 'THIS' keyword in JavaScript and TypeScript - Simple & Code Examples

What is 'THIS' keyword in JavaScript and TypeScript - Simple & Code Examples

You may have heard or read that - this keyword in JavaScript and or/ TypeScript is very confusing and it can be challenging to understand in different contexts.

In my opinion, there's nothing special about the "THIS" keyword, and it's not as complicated as some make it seem.

I believe that starting to learn a new topic, with the preconceived notion that the topic is complicated can slow down your progress. So I would like to ask you, to just for a moment - set aside what you have learned and just assume that this is the first ever thing that you read on the topic.

In this blog post, I aim to simplify the "this" keyword and help you gain a better understanding of how it works.

Just read on, and things will get clearer and clearer.

What is the 'this' keyword?

The 'this' keyword is a designated keyword in JavaScript and TypeScript that refers to the current object or context in which a function or method is executed.

...

It allows you to access the properties and methods of the object that the function or method belongs to.

...

For example, let's say you have a person object with a 'name' and 'age' property, and a method called 'greet' that prints a greeting message with the person's name and age.

You can use the 'this' keyword to refer to the person object inside the 'greet' method like this:

const person = {
  name: "Esther",
  age: 30,
  greet: function() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
};

person.greet(); // Output: "Hello, my name is Esther and I am 30 years old."

In this example, the 'this' keyword inside the 'greet' method refers to the 'person' object, allowing you to access its 'name' and 'age' properties and print them in the greeting message.

In what context is the 'this' keyword commonly used?

The 'this' keyword is commonly used in object-oriented programming to refer to the current instance of an object. It is often used in methods to refer to the properties and methods of the object - just like you saw above.

The 'this' keyword is also used in event handling to refer to the element that triggered the event. In this context, 'this' refers to the DOM element that the event is bound to.

Example of 'this' keyword in JavaScript

Consider the following code snippet:

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.getCarDetails = function() {
    return `Make: ${this.make}, Model: ${this.model}, Year: ${this.year}`
  };
}

const myCar = new Car("Toyota", "Corolla", 2020);
console.log(myCar.getCarDetails()); // Output: "Make: Toyota, Model: Corolla, Year: 2020"

In this example, the 'Car' constructor function creates a new object with the specified properties. The 'getCarDetails' method is a property of the 'Car' object, and when it is called on a 'Car' object, the value of 'this' refers to that object.

Example of 'this' keyword in TypeScript

Consider the following code snippet:

class Person {
  private name: string;
  private age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  public greet(): void {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

const person = new Person("Esther", 30);
person.greet(); // Output: "Hello, my name is Esther and I am 30 years old."

In this example, the 'Person' class defines a new object with the 'name' and 'age' properties. The 'greet' method is a public method of the 'Person' class, and when it is called on a 'Person' object, the value of 'this' refers to that object.

Changing the context

It is important to keep in mind that the value of 'this' can change depending on how the function or method is called, so it is important to be aware of the context in which it is used.

Example in JavaScript:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

const person1 = new Person("Esther", 30);
const person2 = new Person("Jane", 25);

// Call the greet method of person1
person1.greet(); // Output: "Hello, my name is Esther and I am 30 years old."

// Call the greet method of person2
person2.greet(); // Output: "Hello, my name is Jane and I am 25 years old."

// Assign the greet method of person1 to a new variable
const greetFn = person1.greet;

// Call the greet function using the greetFn variable
greetFn(); // Output: "Hello, my name is undefined and I am undefined years old."

In this example, we define a 'Person' class with a 'greet' method that prints a greeting message with the person's name and age. We create two 'Person' objects, 'person1' and 'person2', and call the 'greet' method on each of them, which works as expected.

However, we then assign the 'greet' method of 'person1' to a new variable called 'greetFn', and call it using the 'greetFn' variable. This causes the 'this' keyword inside the 'greet' method to refer to the global object (or undefined in strict mode) instead of the 'person1' object, since the method is no longer called on an object context.

Example in TypeScript:

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

const person1 = new Person("Esther", 30);
const person2 = new Person("Jane", 25);

// Call the greet method of person1
person1.greet(); // Output: "Hello, my name is Esther and I am 30 years old."

// Call the greet method of person2
person2.greet(); // Output: "Hello, my name is Jane and I am 25 years old."

// Assign the greet method of person1 to a new variable
const greetFn = person1.greet;

// Call the greet function using the greetFn variable
greetFn(); // Output: "Hello, my name is undefined and I am undefined years old."

This example is analogous to the JavaScript example I provided earlier, and demonstrates the same pitfall with the 'this' keyword that can arise in both JavaScript and TypeScript.

THIS in JavaScript vs TypeScript

The this keyword is a powerful feature of JavaScript and TypeScript that allows functions to access and manipulate object properties. While this generally works similarly in both languages, there are some differences in behavior that can cause confusion, particularly with respect to class methods.

In JavaScript and TypeScript, the behavior of this is determined by the execution context of the function. While the fundamental behavior is the same in both languages, there are some subtle differences in how this behaves in specific scenarios, such as when a class method is called using super or when this is used in a constructor.

To avoid unexpected behavior with this, it's important to keep track of the execution context and how functions are called. Techniques like call(), apply(), and bind() can be used to explicitly set the value of this for a function, and arrow functions can capture this from the surrounding context.

Overall, working with this in JavaScript and TypeScript isn't overly complicated as long as you understand the execution context and pay attention to how functions are called.