The `this` Keyword
Understand who owns the function, how `call`, `apply`, and `bind` work, and why arrow functions treat `this` differently.
1. What is `this`?
In JavaScript, this simply refers to "the object currently executing this function".
💡 Think of the Pronoun "I" in Conversation
Who does "I" refer to? It depends entirely on who is talking right now! If Alex says "I love pizza", it means Alex. If Priya says "I love pizza", it means Priya. In JavaScript, this depends on which object called the function!
const user1 = {
name: "Alex",
greet() {
console.log("Hello, I am " + this.name);
}
};
const user2 = {
name: "Priya",
greet() {
console.log("Hello, I am " + this.name);
}
};
user1.greet(); // "Hello, I am Alex" (user1 called greet)
user2.greet(); // "Hello, I am Priya" (user2 called greet)
Hello, I am Alex Hello, I am Priya
2. The 4 Simple Rules (How `this` is Decided)
To know what this points to, look at how the function is called:
1. Object Method (Implicit)
Called with a dot: person.speak(). this is the object before the dot (person).
2. Explicit (call, apply, bind)
You explicitly command JavaScript who this should be using .call(obj) or .bind(obj).
3. Constructor (new)
Called with new User(). this is the brand new object just created.
4. Standalone Call (Default)
Called alone: show(). this is global window (or undefined in strict mode).
3. Taking Control: `call()`, `apply()`, and `bind()`
These 3 built-in methods let you borrow functions and set this manually:
function introduce(city, role) {
return `I am ${this.name} from ${city}, working as a ${role}.`;
}
const developer = { name: "Anshuman" };
// 1. call(): Calls function immediately, arguments passed one by one:
console.log(introduce.call(developer, "Bengaluru", "Frontend Lead"));
// 2. apply(): Calls function immediately, arguments passed as an array []:
console.log(introduce.apply(developer, ["Bengaluru", "Frontend Lead"]));
// 3. bind(): Does NOT call immediately. Returns a new permanently bound function:
const boundIntro = introduce.bind(developer, "Bengaluru");
console.log(boundIntro("Fullstack Developer"));
I am Anshuman from Bengaluru, working as a Frontend Lead. I am Anshuman from Bengaluru, working as a Frontend Lead. I am Anshuman from Bengaluru, working as a Fullstack Developer.
4. Arrow Functions Don't Have Their Own `this`!
Arrow functions do not get their own this. Instead, they borrow (inherit) this from whatever scope is around them:
Regular Function Loses `this` ❌
Inside callbacks or setTimeout, regular functions forget who called them and revert to undefined.
Arrow Function Keeps `this` ✅
Arrow functions lock onto the surrounding object's this, making them perfect for event callbacks and timers!
const team = {
title: "Engineering",
members: ["Alex", "Priya"],
printMembers() {
// Arrow function keeps 'this.title':
this.members.forEach(member => {
console.log(`${member} is on the ${this.title} team`);
});
}
};
team.printMembers();
Alex is on the Engineering team Priya is on the Engineering team
5. Quick Comparison Table
| Tool | When to Use | How arguments are passed | Executes immediately? |
|---|---|---|---|
func.call(obj, a, b) |
Borrow a function with a specific this |
Comma-separated list (a, b) |
Yes |
func.apply(obj, [a, b]) |
Borrow a function with arguments already in a list | Array list ([a, b]) |
Yes |
func.bind(obj, a) |
Save a copy to run later (e.g. event handlers) | Comma-separated list | No (Returns copy) |
() => {} (Arrow) |
Callbacks inside methods that need parent's this |
Normal parameters | When called |
6. `this` Keyword Interview Deck
Test your knowledge on implicit vs explicit binding, method extraction lost context, arrow function lexical binding, and hard-binding with bind:
7. Practice Challenge
🎯 Coding Challenge: Function Borrowing & Binding
1. Create an independent function announce(location) that returns `${this.speaker} is presenting '${this.title}' at ${location}`.
2. Execute announce on the presenter object using .call().
3. Create a permanently bound version using .bind() and execute it with "Online Webinar".