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"
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"
Why undefined?
- The arrow function
greetdoesn’t bind its ownthis. - It borrows
thisfrom the environment where it was created, in this case, the global scope (notperson). - In strict mode, global
thisisundefined.
✅ When should you use arrow functions then?
- Great for callbacks (like inside
setTimeoutormap) where you want to use thethisof 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"
Why undefined?
- The function inside
setTimeoutis a plain function. - Nobody “owns” that callback when it runs.
- So
thisdefaults to the global object (windowin browsers) → which has noname.
✅ Fix with an arrow function:
greet: function () {
setTimeout(() => {
console.log("Hello, " + this.name);
}, 1000);
}
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
Why undefined?
- When you pass
app.handleClickdirectly, the function gets detached. - It’s called without an owner object.
- So again,
thisdefaults to global → notextfound.
✅ Fix with .bind (glues this to app):
button.addEventListener("click", app.handleClick.bind(app));
✅ Or wrap it in an arrow function:
button.addEventListener("click", () => app.handleClick());
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 methods →
this= the object calling it - In functions (strict mode) →
this= undefined - In functions (non-strict) →
this= global object - In arrow functions →
this= 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)