DEV Community

Cover image for Everything You Need to Know About JavaScript’s this Keyword
Jonathan Idioseph
Jonathan Idioseph

Posted on

Everything You Need to Know About JavaScript’s this Keyword

1. Why I Care About this

I once broke my app because I didn’t know what this pointed to.
Spoiler: it wasn’t my object.

If you’ve ever seen undefined or TypeError: cannot read property of undefined when using this, welcome to the club. Let’s break it down so you never have to guess again.


2. What is this?

👉 this is a special keyword automatically created when a function is called.

It’s not about where the function was written, it’s about who is calling it at that moment.

JavaScript created this so methods could easily refer back to their owner object without repeating the object’s name every time.

Think of it like pronouns in English:
Instead of saying:

“Jonathan is writing Jonathan’s article.”
We say:
“Jonathan is writing his article.”

Here, this is like “his”, a shortcut to the current owner.


3. this in Normal Functions

const person = {
  name: "Jonathan",
  greet: function () {
    console.log("Hello, my name is " + this.name);
  },
};

person.greet(); 
// "Hello, my name is Jonathan"
Enter fullscreen mode Exit fullscreen mode

Here, the object person is calling greet, so inside the function, this = person.


4. this in Arrow Functions

This is where most developers get confused.
Arrow functions do not create their own this.

Instead, they “look up” and borrow this from the surrounding code (the lexical scope).

Example:

const person = {
  name: "Jonathan",
  greet: () => {
    console.log("Hello, my name is " + this.name);
  },
};

person.greet();
// "Hello, my name is undefined"
Enter fullscreen mode Exit fullscreen mode

Why undefined?

  • The arrow function greet doesn’t bind its own this.
  • It borrows this from the environment where it was created, in this case, the global scope (not person).
  • In strict mode, global this is undefined.

✅ When should you use arrow functions then?

  • Great for callbacks (like inside setTimeout or map) where you want to use the this of the outer function.
  • Bad for object methods, because they won’t refer to the object itself.

So remember:
👉 Arrow functions = “use the this of where I live”
👉 Normal functions = “create my own this when called”


5. Common Situations Where this Trips You Up

❌ Lost this in Callbacks

const person = {
  name: "Jonathan",
  greet: function () {
    setTimeout(function () {
      console.log("Hello, " + this.name);
    }, 1000);
  },
};

person.greet(); 
// "Hello, undefined"
Enter fullscreen mode Exit fullscreen mode

Why undefined?

  • The function inside setTimeout is a plain function.
  • Nobody “owns” that callback when it runs.
  • So this defaults to the global object (window in browsers) → which has no name.

✅ Fix with an arrow function:

greet: function () {
  setTimeout(() => {
    console.log("Hello, " + this.name);
  }, 1000);
}
Enter fullscreen mode Exit fullscreen mode

Now, the arrow function borrows this from greet, which correctly points to person.


❌ Forgetting bind

const button = document.querySelector("button");

const app = {
  text: "Clicked!",
  handleClick: function () {
    console.log(this.text);
  },
};

button.addEventListener("click", app.handleClick);
// undefined
Enter fullscreen mode Exit fullscreen mode

Why undefined?

  • When you pass app.handleClick directly, the function gets detached.
  • It’s called without an owner object.
  • So again, this defaults to global → no text found.

✅ Fix with .bind (glues this to app):

button.addEventListener("click", app.handleClick.bind(app));
Enter fullscreen mode Exit fullscreen mode

✅ Or wrap it in an arrow function:

button.addEventListener("click", () => app.handleClick());
Enter fullscreen mode Exit fullscreen mode

6. The Golden Rule

👉 this is not about where a function is written, but how it is called.

That’s the rule. Once you get that, everything clicks.


7. Quick Reference (Copy This!)

  • In methodsthis = the object calling it
  • In functions (strict mode) → this = undefined
  • In functions (non-strict) → this = global object
  • In arrow functionsthis = borrowed from surrounding scope
  • With .call/.apply/.bind → you manually set this

The this keyword isn’t broken or magical, it’s just contextual.
It was designed to make object methods simpler.

Once you remember: this depends on how the function is called, not where it’s written”, the confusion melts away.

Top comments (0)