Master the concept of 'this' in JavaScript : A to Z explanation

Photo by Jess Bailey on Unsplash

Master the concept of 'this' in JavaScript : A to Z explanation

Learn everything about `this` in JavaScript

JavaScript is all about objects, and that means almost everything in it is like an object. Now, here's the cool part: we can make functions even more awesome by adding extra stuff to them. It's like giving them superpowers! We've talked about this thing called "prototypes" before, which helps us do this. But here's the big question: How do we actually use these supercharged functions? Well, that's where "this" comes in. It's like a magic key that lets us unlock all the cool stuff we've added to our functions.

In JavaScript this keyword refers to the object it belongs to. It has different values depending on where it is used:

  • In an object method, this refers to the owner(Parent) object.

  • Alone, this refers to the global(Parent) object.

  • In a function, this refers to the global(Parent) object.

  • In a function, in strict mode, this is undefined.

  • In an event, this refers to the element that received the event.

  • Methods like call(), and apply() can refer this to any object.

By looking at how we use 'this' in various situations, we can understand that its value changes depending on where it's used. This little word, 'this,' is like a chameleon—it adapts to its surroundings. It's like having a special key to access different things depending on where you are. Understanding 'this' might seem a bit tricky at first, but it's super important, especially in object-oriented programming. You'll find it popping up a lot in functions and methods, so it's a key player in how JavaScript works. Let's understand the concept of this in depth.

What is 'this'? : Learn What Matters!

Just go through the following cases, following which the concept of `this` will be a cakewalk for you:

  1. Calling Functions freely

    When calling a function freely, like in the above example, if we run call the 'conceptOfThis' function in the browser we will get the Window object, compared to this if we run this on our local NodeJS environment we will get the global object when we call 'this'. Hence, in this case, this will refer to the global this.

  2. Calling Functions using 'new' keyword

    Whenever new is used before calling a function, it creates an empty object. This thing is depicted in the above example, when we call the same previous function using the new keyword, the result is an empty object.

  3. `this` inside an arrow function
    Arrow functions work differently when it comes to "this". Inside an arrow function, "this" refers to the value inherited from its surrounding lexical context. You are just a step behind understanding the concept of this in depth, just move on with this case, I will try my best to explain the nature of this is case of arrow functions.
    Have a look on this example:

    In contrast to regular functions, arrow functions do not have their own this value. Instead, this value of the enclosing lexical scope is used. In other words, the value of this inside an arrow function is determined by the context in which it is defined, not where it is called. Analyze the following examples:

    The values of 'this.name' and 'this.ability' are undefined because they are not within the lexical scope for arrow functions. Take a look at the following examples to further understand this concept.

    In this example, the arrow function is bound within the normal function, allowing it to access the values available in the scopes of the normal function. As a result, we can now use the this operator to access the values of the superHero object inside the arrow function.

    Now implement your logic to think and analyze the following example:

    I hope you can examine the above case and understand the logic behind it. If you have any confusion, feel free to ask me. I'll be glad to help. Take a look at these cases and practice them thoroughly to master this concept, which is one of the most commonly asked topics in JavaScript interviews.

  4. Calling function as a method

    Now analyse this piece of code, here we made a simple object having 3 key value pairs, name, ability and printAbility. 'printAbility' function uses this keyword to print the ability of the superhero which can be analysed in the above example. Here, this acts as a reference to the member variables of the object `superhero`.

    For more clarity in above cases, dry run the following example as well.

Common Pitfalls with this Keyword

this keyword can be quite tricky to understand and use properly, and there are a few common pitfalls that developers might encounter when working with it. Here are some of the most common issues:

1. Losing the Context

One of the most common pitfalls with this is losing the context or the value of this within a function. This usually happens when a function is called without its context, which causes this to be bound to the global object (e.g., the window object in a web browser). To avoid this issue, you can use the bind, call, or apply methods to explicitly set the context of the function.

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

person.sayHello(); // This will print "Hello, my name is John"


/*   
     However, if we assign the sayHello function to a variable,
     and then call it without its context, "this" will be bound
     to the global object, and the output will be "Hello, 
     my name is undefined"
*/
const hello = person.sayHello;
hello();

2. Confusion with Arrow Functions

Arrow functions are a relatively new addition to JavaScript, and they behave differently from regular functions when it comes to this. Arrow functions do not have their own this value, but instead, inherit the value of this from the surrounding context. This can lead to confusion when using arrow functions within objects, as the value of this may not be what you expect. For example:

const person = {
  name: 'John',
  sayHello: () => {
    console.log(`Hello, my name is ${this.name}`);
  }
};

// This will print "Hello, my name is undefined"
person.sayHello();

3. Using 'this' in Callback Functions

Callback functions are commonly used in JavaScript, but they can also cause issues with this if not used properly. When a callback function is invoked, the value of this is often different from what you might expect, as it is determined by the function that calls the callback, rather than the callback function itself. To avoid this issue, you can use the bind method to explicitly set the context of the callback function, or use arrow functions, which inherit the context from the surrounding context.

const person = {
  name: 'John',
  friends: ['Alice', 'Bob', 'Charlie'],
  listFriends() {
    this.friends.forEach(function(friend) {
      console.log(`${friend} is a friend of ${this.name}`);
    });
  }
};

/*  
    This will print "undefined is a friend of Alice", "undefined 
    is a friend of Bob", and "undefined is a friend of Charlie"
*/
person.listFriends();

Avoiding 'this' confusion

The behavior of the this keyword can be tricky to understand, especially in complex code. Here are a few tips for avoiding this confusion:

  • Use bind(), call(), or apply() to explicitly set the value of this when calling a function.

  • Use arrow functions, which have a lexical this binding and always refer to the this value of their surrounding context.

Conclusion

The this keyword in JavaScript can be a source of confusion and frustration for many developers, especially those who are new to the language. However, once you understand how it works, it can be a powerful tool for writing more flexible and reusable code.

Remember that the value of this is determined by the context in which a function is called, not where it is defined. Use the call, apply, and bind methods to set this value explicitly, and be careful when using arrow functions. In the upcoming article I will discuss about call, apply and bind methods.

I hope this article has helped you gain a better understanding of this keyword in JavaScript don't forget to refer to MDN documentation after this article. Happy coding!