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
thisissues. - 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