JavaScript's 'this' Keyword: Understand How It Works Under Different Scenarios

Are you confused by the this keyword in JavaScript? It confuses everyone in the beginning, so don’t worry about it. You’re not alone

The this keyword is very commonly used inside functions and objects. Once you understand this, you’ll realize that it’s much simpler than you think it is.

By the end of this article, you would have demystified this for yourself. You’ll know what it is, what it does and how to use it.

**So, what is this?**

Where the function is declared alters what this means. It always refers to one object, usually the object in which the function operates. There five different ways where this can take on new values. They are:

  • A function in global scope
  • A method of an object
  • Function expression as method
  • A simple function
  • Arrow Functions

As you will see, the value of this will change in different situations. But don't worry if you do not follow this on your first read. As you write more functions and objects. these concepts will become more familiar, and if this is not returning the value you expected, this article will help you work out why.

A function in global scope

When a function is created at the top level of a program (that is, not inside another object or function), then it is in the global scope or global context.

The default object in this context is the window object. So when this is used inside a function in the global context, it refers to the window object.

Below, this is being used to return properties of the window object.

function windowSize() {
  let width = this.innerWidth;
  let height = this.innerHeight;
  return [height, width];
}

Under the hood, the this keyword is a reference to the object that the function is created inside.

All global variables also become properties of the window object. So when a function is in the global context, you can access global variables using the window object, as well as its other properties.

Here, the showWidth() function is in global scope, and this.width refers to the width variable:

Illustration of accessing global variables using the window object


Usually, you wouldn’t use this in a global context anyway, so the value of this here doesn’t really matter. Let’s move on to the next one.

A method of an object

When a function is defined inside an object, it becomes a method. In a method, this refers to the containing object.

In the example below, the getArea() method appears inside the shape object, so this refers to the shape object it is contained in.

Illustration of how this works for a method of an object


Because the this keyword here refers to the shape object, it would be the same as writing -

return shape.width * shape.height;

If you were creating several objects using an object constructor (and each shape had different dimensions), this would refer to the individual instance of the new object you are creating. When you called getArea(), it would calculate the dimensions of that particular instance of the object.

Let’s move on to the next context.

Function expression as method

If a named function has been defined in global scope, and it is then used as a method of an object, this refers to the object it is contained within.

The next example uses the same showWidth() function expression as the one that we used earlier, but it is assigned as a method of an object.

Illustration of how this works for a method of a function expression as method

The last but one line indicates that the showWidth() function is used as a method of the shape object. The method is given a different name: getWidth()

When the getWidth() method is called, even though it uses the showWidth() function, this now refers to the shape object, not the global context (and this.width refers to the width property of the shape object). So it prints a value of 300 to the console.

A simple function

Simple functions are functions you know extremely well; like the one below. Anonymous functions written in the same form are also considered simple functions.

function getWidth() {
  //Get Width
}

this is always set to Window in a simple function. The same is true even if you call a simple function in an object method.

function getWidth() {
  console.log(this);
}

const shape = {
  printThis() {
    getWidth();
  },
};

getWidth(); // Window
shape.printThis(); // Window

This is usually tricky for beginners. They expect this to remain the same within object methods. I got caught in it too.

To see why, consider the following code. Here, a this.getWidth() function is executed later within a setTimeout function.

const shape = {
  printLater() {
    setTimeout(function () {
      this.getWidth(); // Error
    }, 1000);
  },
  getWidth() {
    console.log("34.89");
  },
};

Unfortunately, the code above results in an error. The error occurs because this is set to Window in the setTimeout function. Window does not have a getWidth method.

One quick fix is to create a variable that stores the reference to the this.

const shape = {
  printLater() {
    const self = this;
    setTimeout(function () {
      self.getWidth();
    }, 1000);
  },
  getWidth() {
    console.log("34.89");
  },
};

A second way to fix this problem is to use the new ES6 arrow functions, which brings us to the next section.

Arrow Functions

this in an arrow function is always the same as this around it (in its immediate scope). So, if you use arrow functions within an object method, the this context stays as the object, not Window.

With arrow functions, the getWidth example could be written in the following way:

const shape = {
  printLater() {
    setTimeout(() => self.getWidth(), 1000);
  },
  getWidth() {
    console.log("34.89");
  },
};

Summary

In this article, you learned about the five different contexts where this takes on different values.

That’s all you need to know about this. Just master the concepts taught in this article and you won’t ever get confused anymore.

Get my free, weekly JavaScript tutorials

Want to improve your JavaScript fluency?

Every week, I send a new full-length JavaScript article to thousands of developers. Learn about asynchronous programming, closures, and best practices — as well as general tips for software engineers.

Join today, and level up your JavaScript every Sunday!

Thank you, Taha, for your amazing newsletter. I’m really benefiting from the valuable insights and tips you share.

- Remi Egwuda