Skip to main content

Command Palette

Search for a command to run...

Understanding the this Keyword in JavaScript

Updated
•4 min read•View as Markdown
Understanding the this Keyword in JavaScript

JavaScript’s this keyword is one of the most commonly misunderstood concepts, not because it is complex, but because it behaves differently depending on how a function is called. The simplest and most accurate way to understand this is it refers to the caller of the function. Once you adopt this mental model, most confusion disappears.

This article explains this step by step using practical examples, avoiding unnecessary internal details.

What this Represents

At its core, this is a reference to the object that is currently executing the function. It is not fixed when the function is written—it is determined at runtime based on how the function is invoked.

this in Global Context

When code runs at the top level (not inside any function), this refers to the global object.

In browsers:

console.log(this); // window

So in a browser environment, this === window. But in strict mode implicit binding implemented to avoid bugs. This difference matters when debugging unexpected this values.

this Inside Objects

When a function is called as a method of an object, this refers to that object.

Example:

const user = {
  name: "Pritam",
  greet() {
    console.log(this.name);
  }
};

user.greet(); // Pritam

Breaking the Reference

If you extract the function and call it separately:

const greetFn = user.greet;
greetFn();

Output:

undefined

Now that the function is called without an object, this is no longer user.

this Inside Functions

When a normal function is called independently:

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

show();

In non-strict mode:

window

In strict mode:

undefined

Arrow Functions and this

Arrow functions behave differently. They do not have their own this. Instead, they inherit this from the surrounding scope.

Example:

const user = {
  name: "Pritam",
  greet: () => {
    console.log(this.name);
  }
};

user.greet(); // undefined

Arrow function does not bind this to user. It takes this from where it was defined (global scope).

Correct Usage:

const user = {
  name: "Pritam",
  greet() {
    const inner = () => {
      console.log(this.name);
    };
    inner();
  }
};

user.greet(); // Pritam

How Calling Context Changes this

This is the most important part. The value of this changes based on how the function is called, not how it is written.

1. Method Call

const obj = {
  value: 10,
  getValue() {
    return this.value;
  }
};

obj.getValue();

→ this = obj

2. Function Call

const fn = obj.getValue;
fn();

→ this = window (or undefined in strict mode)

3. Using call

function greet() {
  console.log(this.name);
}

const person = { name: "Pritam" };

greet.call(person);

Output:

Pritam

Here call() explicitly sets this.

4. Using apply

Same as call, but arguments are passed as an array:

greet.apply(person);

5. Using bind

const boundFn = greet.bind(person);
boundFn();

Output:

Pritam

bind returns a new function with fixed this.

Common Mistakes

1. Losing this in callbacks

const user = {
  name: "Pritam",
  show() {
    setTimeout(function () {
      console.log(this.name);
    }, 1000);
  }
};

user.show();

Output:

undefined

Fix with arrow function:

setTimeout(() => {
  console.log(this.name);
}, 1000);

2. Using arrow functions as methods

Avoid:

const obj = {
  name: "Test",
  show: () => console.log(this.name)
};

Because this won’t refer to obj.

Conclusion

Most bugs related to this come from losing the calling context. Instead of focusing on JavaScript internals, focus on how the function is invoked in real code paths. That perspective scales better in real-world applications, especially when working with event handlers, callbacks, and frameworks.

More from this blog