What is this in JavaScript?🤔

JavaScript

readTime

8 min

What is this in JavaScript?🤔

If you program in JavaScript regularly, you've probably come across the mysterious this keyword.

At first, it may seem very complicated and confusing.

But don't worry! 😉 In this article, I'll explain exactly what this is in JavaScript, how it works in different contexts, and why it's important to understand what it refers to in various situations.

I'll show you how this functions in the global context, in object methods, arrow functions, constructor functions, and also when using methods like bind(), call(), and apply().

Let's get started 🚀

Introduction to this in JavaScript 🧑‍💻

This in JavaScript refers to the context in which a function is called, and its value can vary depending on how the function is defined and used.

This means that in one case, this may refer to the global object, while in another case, it may refer to a specific object or an instance created by a constructor function.

At first, this might sound complex, but in reality, there are some clear rules that allow you to understand how this works in different contexts.

Here are the main use cases for this:

  • Global contextthis refers to the global object, which is window in browsers or global in Node.js.
  • Object methodsthis refers to the object that calls the method.
  • Arrow functionsthis inherits its context from where the function was defined, not where it was called.
  • Constructor functionsthis refers to the newly created object instance.
  • Methods like bind(), call(), and apply() – these methods allow you to manually manipulate the value of this, setting it to any object.

Understanding how this works is essential if you want to master JavaScript and build efficient and flexible applications.

This in the Global Context 🌐

In the global context, this refers to the global object. In browsers, this is the window object, meaning that when a function is called in the global context, this defaults to pointing to the window object.

javascript
function showThis() {
  console.log(this); // window object in the browser
}

showThis();

As you can see above, calling the showThis() function in a browser results in this referring to the window object. In a Node.js environment, the value of this in the global context points to the global object.

However, when working in strict mode, the value of this in the global context changes and returns undefined. Let's see how that works.

Strict Mode 🚨

When you enable strict mode in JavaScript (by adding "use strict"; at the beginning of a file or function), JavaScript becomes more restrictive in certain situations, which can help avoid errors that might go unnoticed in normal mode.

One of the side effects of enabling strict mode is the change in behavior of this in the global context.

javascript
"use strict";

function showThisStrict() {
  console.log(this); // undefined
}

showThisStrict();

As you can see, after enabling strict mode, this in the global context returns undefined instead of referring to the window object.

This helps prevent accidental references to global objects, which is a common source of errors in larger applications.

This in Object Methods 🛠️

When a function is called as a method of an object, the value of this refers to that specific object. Let's take a look at the following example:

javascript
const person = {
  name: "Alice",
  introduce() {
    console.log(`Hi! My name is ${this.name}`); // Hi! My name is Alice
  },
};

person.introduce();

In this case, this refers to the person object because it is the one calling the introduce() method.

This means that you can access the properties of the object inside its methods using the this keyword.

However, it's important to be aware of one common source of confusion with this – situations where an inner function is defined inside an object's method.

This in Object Methods and Inner Functions 🤯

When you define an inner function within an object's method, the value of this inside that function may change. Let's see this in practice:

javascript
const person = {
  name: "Alice",
  introduce() {
    function innerFunction() {
      console.log(this.name); // undefined
    }
    innerFunction();
  },
};

person.introduce();

Why does this return undefined? This happens because this inside the innerFunction() refers to the global object (window in browsers) rather than the person object.

To avoid such issues, arrow functions are often used, as they handle this differently.

Arrow Functions 🏹

Arrow functions in JavaScript introduce a key difference in the behavior of this.

In traditional functions, the value of this depends on how the function was called.

However, arrow functions have lexical this, meaning they inherit the value of this from the place where they were defined.

Let's see an example:

javascript
const person = {
  name: "Alice",
  introduce() {
    const innerFunction = () => {
      console.log(this.name); // Alice
    };
    innerFunction();
  },
};

person.introduce();

In this case, because innerFunction is an arrow function, this inherits its value from the surrounding context, which is the introduce() method. Therefore, this refers to the person object.

Thanks to arrow functions, we can avoid issues with this inside inner functions.

This is one of the main reasons arrow functions have become so popular in modern JavaScript.

This in Constructor Functions 🏗️

Constructor functions in JavaScript are special functions used to create new object instances.

When a function is called as a constructor (using the new keyword), this refers to the newly created object instance.

Let's take a look at an example:

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

const john = new Person("John", 28);
console.log(john.name); // John
console.log(john.age); // 28

In this case, when we call the Person function using new, we create a new object instance, and this refers to that instance (john).

The constructor allows us to assign properties to the newly created objects.

Manipulating this with bind(), call(), and apply() 🔄

Sometimes, we need to manually modify the value of this for a given function.

In such cases, we can use the methods bind(), call(), and apply(). Here's how each of them works in practice:

  • call() – invokes a function with this set to any object you pass as the first parameter.
javascript
function greet() {
  console.log(`Hello, my name is ${this.name}`);
}

const person = { name: "Tom" };

greet.call(person); // Hello, my name is Tom
  • apply() – works similarly to call(), but instead of passing arguments directly, you need to provide them in an array.
javascript
function introduce(age, city) {
  console.log(`${this.name} is ${age} years old and lives in ${city}`);
}

const person = { name: "Lucy" };

introduce.apply(person, [25, "New York"]); // Lucy is 25 years old and lives in New York
  • bind() – creates a new function where this is permanently set to the chosen object.
javascript
function sayHello() {
  console.log(`Hello, ${this.name}`);
}

const person = { name: "Kate" };

const boundSayHello = sayHello.bind(person);
boundSayHello(); // Hello, Kate

Unlike call() and apply(), the bind() method does not invoke the function immediately. Instead, it returns a new function with the bound this value, which you can call later.

This and ES6 Classes 👷‍♀️

Since the introduction of classes in ES6, working with constructor functions has become more intuitive. Classes offer a clearer and more concise syntax for creating objects and working with this.

javascript
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise`);
  }
}

const dog = new Animal("Dog");
dog.speak(); // Dog makes a noise

As we can see, in the case of ES6 classes, this in methods refers to the object instance created by the constructor (dog in this example).

Conclusion 🎯

This in JavaScript is a crucial concept that allows you to manage the context of function calls dynamically.

Depending on where and how a function is called, this can refer to the global object, a specific object, or a newly created instance.

Understanding how this works is essential for any developer who wants to write efficient and flexible JavaScript code.

Arrow functions simplify working with this, eliminating the problem of changing context, while methods like bind(), call(), and apply() give you full control over assigning this.

The introduction of ES6 classes further simplifies working with this in constructors, making the code more readable and concise.

I hope this article helped you understand the workings of this in JavaScript and makes it easier for you to continue mastering your craft.

authorImg

Witek Pruchnicki

I passionately share knowledge about programming and more in various ways.