Arrow functions don’t follow the usual this
rules. Here are 6 simple examples to finally make it click.

this
rules. Here are 6 simple examples to finally make it click.Introduction: The “Why is this
Undefined?” Problem
Every JavaScript dev runs into this:
const user = {
name: "Ali",
greet: () => `Hi, I’m ${this.name}`
};
console.log(user.greet());
// ❌ "Hi, I'm undefined"
If you expected "Ali"
, you’re not alone.
The reason? Arrow functions don’t create their own this
.
Instead, they inherit this
from their surrounding scope (lexical scoping). This is both super useful and super confusing if you don’t know the rules.
Let’s break it down with 6 simple examples.
1. Regular Function vs Arrow Function in Objects
Regular Function (✅ Works)
const user = {
name: "Sara",
greet: function () {
return `Hi, I’m ${this.name}`;
}
};
console.log(user.greet());
// "Hi, I'm Sara"
Arrow Function (❌ Breaks)
const user = {
name: "Sara",
greet: () => `Hi, I’m ${this.name}`
};
console.log(user.greet());
// "Hi, I'm undefined"
💡 Takeaway: Use regular functions for object methods — arrows won’t bind this
to the object.
2. Arrow Functions Fix Callback this
One of the biggest pains in JavaScript is losing this
inside callbacks.
Traditional Function (❌ Loses this
)
function Timer() {
this.seconds = 0;
setInterval(function () {
this.seconds++; // ❌ 'this' is global
}, 1000);
}
Arrow Function (✅ Inherits this
)
function Timer() {
this.seconds = 0;
setInterval(() => {
this.seconds++; // ✅ Refers to Timer
}, 1000);
}
const t = new Timer();
setTimeout(() => console.log(t.seconds), 3100); // ~3
💡 Takeaway: Use arrows for timers, promises, and callbacks that need parent this
.
3. Arrow Functions Inside Classes
In class methods, arrows help avoid .bind(this)
boilerplate.
class Button {
constructor(label) {
this.label = label;
}
click = () => {
console.log(`Clicked: ${this.label}`);
};
}
const saveBtn = new Button("Save");
saveBtn.click();
// "Clicked: Save"
✅ No need for manual binding in the constructor.
4. Arrow Functions Don’t Work in Event Listeners
In DOM events, this
usually refers to the element. Arrows break that.
const button = document.querySelector("button");
button.addEventListener("click", () => {
console.log(this); // ❌ Window
});
✅ Fix with a regular function:
button.addEventListener("click", function () {
console.log(this); // ✅ The button element
});
💡 Rule: Use regular functions when you need this
bound to the element.
5. Arrow Functions Can’t Be Constructors
Arrows don’t support 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"
6. Arrow Functions Simplify Nested Functions
Before arrows, devs used hacks like const self = this
.
function Counter() {
this.count = 0;
const self = this;
function increment() {
self.count++;
}
increment();
console.log(this.count); // 1
}
With arrows:
function Counter() {
this.count = 0;
const increment = () => {
this.count++;
};
increment();
console.log(this.count); // 1
}
💡 Takeaway: Arrows make nested functions much cleaner.
Wrapping It All Up
Here are the 6 key examples of this
in arrow functions:
- Object methods → regular functions work, arrows break.
- Callbacks (timers, async) → arrows fix
this
issues. - Classes → arrows prevent
.bind(this)
boilerplate. - Event listeners → regular functions keep element
this
. - Constructors → only regular functions work.
- Nested functions → arrows simplify scoping.
👉 Bottom line: Arrow functions are not just shorthand. They change the rules of this
— sometimes that’s a blessing, sometimes a bug.
Call to Action
👉 Have you been bitten by a this
bug before? Drop your story in the comments 👇.
📤 Share this with a teammate who still forgets how this
works.
🔖 Bookmark this guide for quick reference.
Leave a Reply