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
greet
doesn’t bind its ownthis
. - It borrows
this
from the environment where it was created, in this case, the global scope (notperson
). - In strict mode, global
this
isundefined
.
✅ When should you use arrow functions then?
- Great for callbacks (like inside
setTimeout
ormap
) where you want to use thethis
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"
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 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.handleClick
directly, the function gets detached. - It’s called without an owner object.
- So again,
this
defaults to global → notext
found.
✅ 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)