Confused about why this
works differently in arrow functions? Here are 5 beginner-friendly rules with examples to make it click.

this
works differently in arrow functions? Here are 5 beginner-friendly rules with examples to make it click.Introduction: The Mysterious this
Bug
Every JavaScript beginner hits this wall:
const user = {
name: "Ali",
greet: () => `Hi, I’m ${this.name}`
};
console.log(user.greet());
// ❌ "Hi, I'm undefined"
Wait… why isn’t it printing Ali
?
If you’ve asked yourself that question, you’re not alone.
Arrow functions handle this
completely differently from traditional functions. That’s not a bug — it’s by design. Once you know the rules, you’ll avoid hours of debugging.
Here’s your beginner-friendly guide: 5 key rules about this
in arrow functions.
Rule 1: Arrow Functions Don’t Bind Their Own this
Traditional functions decide this
based on how they’re called. Arrow functions capture this
from their parent scope.
function Timer() {
this.seconds = 0;
setInterval(() => {
this.seconds++; // ✅ uses Timer's this
}, 1000);
}
const t = new Timer();
setTimeout(() => console.log(t.seconds), 3100); // ~3
💡 Remember: Arrow = lexical this
(whatever scope they’re in).
Rule 2: Don’t Use Arrows for Object Methods
Arrows don’t bind this
to the object — which breaks methods.
const user = {
name: "Sara",
greet: () => `Hi, I’m ${this.name}`
};
console.log(user.greet());
// ❌ "Hi, I'm undefined"
✅ Fix with a regular function:
const user = {
name: "Sara",
greet() {
return `Hi, I’m ${this.name}`;
}
};
console.log(user.greet());
// "Hi, I'm Sara"
Rule 3: Arrows Shine in Callbacks
One of the biggest headaches in JavaScript is losing this
in callbacks. Arrows fix that.
class Button {
constructor(label) {
this.label = label;
}
click() {
setTimeout(() => {
console.log(this.label); // ✅ "Save"
}, 500);
}
}
const b = new Button("Save");
b.click();
💡 Use arrows inside class methods, timers, and promises where callbacks need the outer this
.
Rule 4: Don’t Use Arrows as Constructors
Arrow functions can’t be used with new
.
const Person = (name) => { this.name = name; };
new Person("Ali");
// ❌ TypeError: Person is not a constructor
✅ Use a regular function or class:
function Person(name) {
this.name = name;
}
const p = new Person("Ali");
console.log(p.name); // "Ali"
Rule 5: Event Handlers Need Care
In DOM event handlers, this
usually refers to the element. Arrows don’t give you that.
const button = document.querySelector("button");
button.addEventListener("click", () => {
console.log(this); // ❌ Window, not button
});
✅ Use a regular function if you need this
bound to the element:
button.addEventListener("click", function () {
console.log(this); // ✅ Refers to the button
});
Wrapping It All Up
Here are the 5 key rules for beginners:
- Arrows don’t bind their own
this
— they inherit from the parent scope. - Don’t use arrows for object methods.
- Use arrows in callbacks to preserve outer
this
. - Arrows can’t be constructors.
- Be careful in event handlers — sometimes you need traditional functions.
👉 Bottom line: Arrow functions are amazing for cleaner callbacks and functional programming, but traditional functions are still essential for methods, events, and constructors.
Call to Action
👉 Did one of these rules finally clear up a bug you’ve had? Drop it in the comments 👇.
📤 Share this with a teammate who keeps forgetting how this
works.
🔖 Bookmark this as your go-to this
survival guide.
Leave a Reply