Skip to main content

Command Palette

Search for a command to run...

Understanding the this Keyword in JavaScript

Published
6 min read

In JavaScript, the this keyword is important. It helps by managing the context where a function operates. It allows functions have an interaction with objects, which helps in making codes organized and can be reused. As a developer, to make it easy for you to work with objects and functions, you have to understand this.

Some developers at times experience difficulties in understanding this and it is because its value can change depending on where a function is called. It is very common for developers to think that this refers to the function itself or the object containing the function. But its true value depends on the context.

This article will cover the this keyword in JavaScript. We’ll learn how it works in the global and functional context. We will also look at this in constructor and arrow functions and also common mistakes with the tips to avoid them.

Understanding this in Global Context

When used in a global context, the this keyword refers to the global object meaning outside of any function or object. In a browser (e.g. Chrome, Firefox, and so on), the global object here is window while in Node.js it's global. What this means is that, when we use this outside of any function or object as the case may be, it points to the global object.

Let's look at this example below:

// In a browser environment
window.name = "Hannah";
console.log(this.name);

image

From the example shown above, we can see that just by assigning to window, the variables become properties of the global object, and this.name will output its expected value correctly.

// Example in Node.js environment
global.name = "Kalio";
console.log(this.name); // Outputs: "Kalio"

In this second example, we can see that global.name sets the variable name to Kalio. In Node.js, this inside a module will refer to the module itself and not the global object.

this in Function Context

In a standard function, the meaning of this changes based on how you call the function. When you use it as an object's method, this points to the object you're using the method on. This lets the function work with and change that object's properties.

Let's see this example:

const person = {
  name: "Hannah",
  sayHi: function () {
    console.log(this.name);
  },
};

person.sayHi();

image

From this example above, we can see that this is inside the sayHi method and it refers to the object called person. Now, when the person.sayHi() is called, the sayHi method runs. The sayHi method has this.name nested inside it, which then outputs its value Hannah.

this in Constructor Functions

Constructor functions are like blueprints for creating objects. When using the this keyword with constructor functions, it creates an object (a new object). this refers to a newly created object when inside a constructor function.

Let's see this example:

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

// Create a new person object
const person1 = new Person("Hannah", 30);

console.log(person1);

image

In the above example, Person is a constructor function that has in it this.name and this.age which creates properties for the new object. The new Person("Hannah", 30) creates a new object entirely and then assigns it to person1. this in this constructor function refers to the person1 object.

this in Arrow Functions

When a function inherits this value from its surrounding environment, it is called Lexical scoping. Arrow functions exhibit lexical scoping because it does not have its own this rather it uses the this of the code where it is defined.

Example:

const person2 = {
  name: "Kalio",
  sayHi: () => {
    console.log("Hello, my name is " + this.name);
  },
};
person2.sayHi();

image

In this example, the arrow function does not have its own rather it looks outside and finds the global object (or window in a browser) making this.name undefined.

Binding this

So far we've learned that in JavaScript, this refers to the object that has the code currently being executed. When this default behavior doesn't suit what you need it for you can set its values using these methods namely: call, apply, and bind.

Let's look at these methods one after another:

  • call():
    The call() method allows you to set this value for a function when it's invoked. This method tells a function: "Hi, I want you to act like you belong to this other object." It takes two or more arguments.
function hello(greet) {
  console.log(`${greet}, ${this.firstName} ${this.lastName}`);
}

const person = { firstName: "Hannah", lastName: "Kalio" };

hello.call(person, "Good morning");

image

In this example, the hello is the function to be called. The person is the object to be set as this within the hello function and Good morning is the argument passed to the hello function.

  • apply():
    Similar to the just discussed method (call()), the apply() method allows you to set this value for a function but its arguments are passed in an array.
function hello(greet, punctuation) {
  console.log(`${greet}, ${this.firstName} ${this.lastName}${punctuation}`);
}

const person = { firstName: "Hannah", lastName: "Kalio" };

hello.apply(person, ["Hi", "!"]);

image

From the example, you can see that the argument is passed as an array (['Hi', '!']).

  • bind():
    Let's say you want to create a function to be used later with a specific owner, the bind() method is what you should use. It creates a new function with a fixed this value.

Let's see how the bind works:

const person = {
  name: "Hannah Kalio",
};

function sayHi(greet) {
  console.log(greet + ", " + this.name);
}

const greetPerson = sayHi.bind(person);
greetPerson("Hey");

image

We can see here that by using bind(), we created a new function greetPerson with a fixed context making it easy to use with the correct this value later.

Common mistakes made with this and tips for avoiding common issues

As developers, the this keyword in JavaScript can be very tricky and mistakes are bound to occur. A common mistake we make as developers is expecting this to behave the same way in arrow functions as in regular functions which isn't possible because this is lexically scoped in arrow functions and not in regular functions. Also at times, we forget to bind this in Event handlers or we can also get confused with this in Nested Functions. To avoid these mistakes, you can do the following:

  • Use helper variables (self or that) in situations where you need to maintain the this context in nested functions to store the this value from the outer function.

  • Bind this explicitly when necessary.

  • Use arrow functions for callbacks.

  • Practice regularly using codes that use the this keyword in several contexts.

Conclusion

For you as a developer to write clear and effective code, you need to understand the this keyword in JavaScript. this will enhance your ability to create good applications whether you are dealing with callbacks or constructor functions. Regular practice will deepen your knowledge and will help you become proficient in handling this in JavaScript.