Skip to main content

Command Palette

Search for a command to run...

The this Keyword in JavaScript: The Mental Model Most Developers Miss

Updated
5 min read
The this Keyword in JavaScript: The Mental Model Most Developers Miss
A
I create websites, I'm a weber!

You’ve written the function correctly. The object is right there. But this returns undefined and you have no idea why. Sound familiar? That’s not a bug — that’s this doing exactly what it’s designed to do. You just didn’t know the rules. Let’s fix that.

**Why JavaScript Introduced the this Keyword?
**Before understanding this, you need to understand the problem it was built to solve.
Imagine you have an object with a method:

const user = {
  name: "Asha",
  greet: function() {
    console.log(user.name); // hardcoded
  },
};
user.greet(); // "Asha"

This works — but it’s fragile. The method is hardcoded to the variable name user. The moment you try reusing this function on another object, it breaks:

const user2 = {
  name: "Ayushmann",
  greet: user.greet,
};
user2.greet(); // still prints "Asha" — not what we wanted

Two problems here:

  1. The method can’t refer to itself dynamically, it’s locked to one specific variable name.

  2. The function is not reusable hardcoded to user, useless everywhere else.

This is exactly the kind of problem that makes large codebases a nightmare to maintain.

**this to the Rescue
**this solves both problems by letting the function dynamically refer to whoever is calling it no hardcoding needed:

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

person.sayHi(); // "Sonam"
const person1 = {
  name: "Sakshi",
  sayHi: person.sayHi,
};

person1.sayHi(); // "Sakshi"

Same function. Two different objects. Correct output both times.
this automatically points to whoever called the method. That’s the core superpower dynamic self-reference and reusability.

**The One Rule Seniors Know
**Here’s the single line that separates juniors from seniors when explaining this:

this is not about where a function is written — it’s about how it is called.

this is decided at runtime, not when the function is defined. This is called runtime binding and it’s the mental model you need before everything else clicks.

**Why this Behaves Differently in Callbacks?
**Here’s the thing and where most developers get caught off guard.

Because this is dynamic, its value shifts depending on the context. And that context-shifting creates bugs that are surprisingly hard to trace.

Here’s one every JavaScript developer has hit at least once:

const user = {
  name: "Asha",
  greet: function() {
    setTimeout(function() {
      console.log(this.name); // undefined
    }, 1000);
  }
};

user.greet();

You’d expect “Asha” — but you get undefined.
Why? The callback inside setTimeout is a regular function. By the time it runs, it’s no longer being called by user — it’s called by the JavaScript runtime in the global context.

So this quietly loses its connection to user and points to window instead. And window.name is not “Asha”.
This is the trap — this silently shifts context inside callbacks. No error, no warning. Just wrong output.

**How Arrow Functions Fix the this Problem?
**Remember — arrow functions don’t have their own this. They inherit it from the surrounding scope. That’s exactly what saves us here:

const user = {
  name: "Asha",
  greet: function() {
    setTimeout(() => {
      console.log(this.name); // "Asha"
    }, 1000);
  }
};

user.greet();

The arrow function inherits this from the outer greet function — which correctly points to user.
But here’s what most articles miss — the arrow function is not always the hero:

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

user.greet();

When you use an arrow function as the method itself, it inherits this from the surrounding scope — which is the global context, not user. So you’re back to undefined.
Same feature, completely opposite results depending on where you use it:

  1. Arrow function as an object method → trap

  2. Arrow function inside a method as a callback → solution

This is what interviewers are actually testing when they ask about arrow functions and this. Not the definition — the distinction.

**How to think as a Senior developer?
**“Who is calling this function, and in what context?”

That single question will tell you what this is in any situation. You don’t need to memorise every case — you need the right mental model.
And when this still doesn’t behave — that’s when you need to take explicit control over its value.

Arrow functions fix one trap. But what happens when you can’t use an arrow function? What if this is still pointing to the wrong object and you need to force it to point somewhere specific?

That’s where call, apply, and bind come in — and that’s exactly what Part 2 covers.

**JavaScript this Keyword — Quick Reference Cheat Sheet
**Save this for your next interview:

  1. Browser global scope → window

  2. Regular function (non-strict) → window

  3. Regular function (strict mode) → undefined

  4. Object method → the object itself

  5. Arrow function → inherits from parent scope

  6. Class constructor → the new instance

  7. Event listener → the DOM element

If this clicked for you, Part 2 is coming — where I break down call, apply, and bind with the same depth. Follow so you don't miss it.

More JavaScript content — Medium

Happy Coding! 🚀

More from this blog

J

JS with ashaa

2 posts

Practical JavaScript concepts for developers preparing for frontend interviews. Covers closures, scope, async patterns, DSA, and more — with coding exercises to actually test your understanding.