Skip to main content

Command Palette

Search for a command to run...

Understanding 'this' Keyword in JavaScript

Understand how "this" works in JavaScript across different contexts

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

Introduction

Few concepts in JavaScript confuse developers as consistently as this. Not because it’s complex in implementation, but because it behaves differently depending on how a function is called.

If you try to memorize rules, you’ll keep getting it wrong. If you understand the underlying principle, it becomes predictable.

Here is that principle:

this is determined by the caller of the function, not where the function is written.

Once you internalize that, most confusion disappears.

What this Actually Represents

At its simplest, this refers to the object that is executing the current function.

But that definition is incomplete unless you add one critical detail:

The value of this is decided at call time, not at definition time.

That means the same function can have different this values depending on how it is invoked.

The Caller–Function Relationship

https://images.openai.com/static-rsc-4/yfNYs3IgSIBQGj-kC3kIgR00C5WAwruOdWGgLpAwo-Jxqa-AAGzb612Ahy79erqOwkm76xkmfCxhxalZLyZS1APX-EVlQsTPiix72o-uJ1H87DXiDM3BT5symy3Pwf3d976-ZzDdiCFUto4z4KG3hMop7GwS4yHlIi_yG8dwfzhKQdYgFIzQJ6eKeciOV6YK?purpose=fullsize

To understand this, always ask:

“Who is calling this function?”

That caller becomes the value of this.

this in the Global Context

In the global scope, this behaves differently depending on the environment.

console.log(this);
  • In browsers → window

  • In Node.js → global (or {} in strict modules)

Insight

Global this is rarely useful in modern code. Relying on it often leads to unclear dependencies and harder-to-maintain logic.

this Inside Regular Functions

This is where things start to break for most developers.

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

show();

In non-strict mode:

  • this → global object

In strict mode:

  • this → undefined

Insight

This is a common source of bugs. Functions that are not tied to an object lose their context unless explicitly controlled.

this Inside Objects

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

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

user.greet(); // "Alice"

Here, user is the caller, so this points to user.

This is the most intuitive and expected behavior.

How Calling Context Changes this

The same function can behave differently depending on how it’s called.

const obj1 = {
  name: "A",
  show() {
    console.log(this.name);
  }
};

const obj2 = {
  name: "B"
};

obj2.show = obj1.show;

obj2.show(); // "B"

The function is identical. Only the caller changed.

This proves that this is not tied to the function—it’s tied to the call site.

Arrow Functions and this

Arrow functions behave differently. They do not have their own this.

Instead, they inherit this from their surrounding scope.

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

obj.greet(); // undefined

Here, this is not obj. It comes from the outer scope (likely global).

Insight

Arrow functions are not suitable for object methods when you rely on this.

Controlling this Explicitly

JavaScript gives you ways to control this manually:

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

const user = { name: "Alice" };

greet.call(user); // Alice

You can use:

  • call() → pass arguments individually

  • apply() → pass arguments as array

  • bind() → create a new function with fixed this

These are not optional tools—they are essential when dealing with dynamic contexts.

A Practical Mental Model

Stop thinking in terms of rules. Think in terms of invocation.

Whenever you see this, ask:

  1. Is this function called by an object?

  2. Is it a standalone function?

  3. Is it an arrow function?

  4. Is this being manually set?

If you answer these, you’ll always know what this is.

Conclusion

The this keyword is not unpredictable—it’s just misunderstood.

It does not depend on where the function is written.
It does not depend on variable names.

It depends entirely on how the function is called.

If you focus on that single idea, most of the confusion disappears.

If you ignore it, this will keep breaking your code in subtle ways.

The difference is not in complexity—it’s in how you think about execution.