The this Keyword: Your JavaScript Identity Badge đ
The Big Idea
Imagine youâre at a costume party. When someone asks, âWho are you?â your answer depends on which costume youâre wearing right now.
In JavaScript, this works the same way. Itâs like asking, âWho am I right now?â The answer changes based on how and where a function is called.
Simple Rule:
this= âthe thing thatâs calling me right nowâ
Understanding this
Think of this like a name tag that changes depending on the room youâre in.
At Home (Global Context)
When youâre just hanging out, not inside any object:
console.log(this);
// In browser: Window object
// In Node.js: global object
Itâs like being in a big playground. When no one specific calls you, you belong to the whole playground!
Inside an Object
const dog = {
name: "Buddy",
bark: function() {
console.log(this.name + " says woof!");
}
};
dog.bark(); // "Buddy says woof!"
The dog is calling bark(), so this = dog. Simple!
this in Different Contexts
Letâs see how this changes costumes in different situations.
1. Regular Function
function sayHello() {
console.log(this);
}
sayHello();
// Global object (or undefined in strict mode)
No one specific called it, so this points to the big boss (global).
2. Object Method
const cat = {
name: "Whiskers",
meow: function() {
console.log(this.name);
}
};
cat.meow(); // "Whiskers"
The cat is calling meow(), so this = cat.
3. Event Handler
button.addEventListener('click', function() {
console.log(this); // The button element!
});
The button called the function, so this = button.
4. Constructor Function
function Person(name) {
this.name = name;
}
const alice = new Person("Alice");
console.log(alice.name); // "Alice"
When you use new, this becomes the brand new object being created!
graph TD A["Who is calling the function?"] --> B{Global call?} B -->|Yes| C["this = global/window"] B -->|No| D{Object method?} D -->|Yes| E["this = the object"] D -->|No| F{Constructor with new?} F -->|Yes| G["this = new object"] F -->|No| H{Event handler?} H -->|Yes| I["this = element"]
Arrow Function this Behavior
Arrow functions are special. Theyâre like sticky name tags that never change.
The Problem with Regular Functions
const person = {
name: "Bob",
friends: ["Alice", "Charlie"],
greetFriends: function() {
this.friends.forEach(function(friend) {
console.log(this.name + " says hi to " + friend);
// undefined says hi to Alice đ˘
});
}
};
Inside forEach, this changed! Itâs not Bob anymore.
Arrow Functions Save the Day!
const person = {
name: "Bob",
friends: ["Alice", "Charlie"],
greetFriends: function() {
this.friends.forEach((friend) => {
console.log(this.name + " says hi to " + friend);
// Bob says hi to Alice â
});
}
};
Arrow functions donât have their own this. They look at their parent and copy that this. Like a child wearing their parentâs name tag!
Quick Comparison
| Regular Function | Arrow Function |
|---|---|
Gets its own this |
Borrows parentâs this |
this can change |
this stays locked |
| Good for methods | Good for callbacks |
The call Method
Think of call() as a costume change button. You can force a function to pretend it belongs to any object you want!
Basic Example
function introduce() {
console.log("Hi, I'm " + this.name);
}
const superhero = { name: "Spider-Man" };
const villain = { name: "Thanos" };
introduce.call(superhero); // "Hi, I'm Spider-Man"
introduce.call(villain); // "Hi, I'm Thanos"
Youâre telling the function: âFor this call, pretend this is superhero (or villain).â
With Arguments
function greet(greeting, punctuation) {
console.log(greeting + ", " + this.name + punctuation);
}
const user = { name: "Emma" };
greet.call(user, "Hello", "!");
// "Hello, Emma!"
Pass arguments one by one after the object.
The apply Method
apply() is call()'s twin sibling. The only difference? Arguments come in an array.
Same Example, Different Style
function greet(greeting, punctuation) {
console.log(greeting + ", " + this.name + punctuation);
}
const user = { name: "Emma" };
// call: arguments one by one
greet.call(user, "Hello", "!");
// apply: arguments in an array
greet.apply(user, ["Hello", "!"]);
// Same result: "Hello, Emma!"
When to Use Apply?
When you already have arguments in an array!
const numbers = [5, 2, 9, 1, 7];
// Find the maximum
Math.max.apply(null, numbers); // 9
Memory Trick:
- Apply = Array
- Call = Commas (separate arguments)
The bind Method
bind() is like creating a permanent costume. It creates a new function with this locked forever.
The Difference
const hero = {
name: "Batman",
introduce: function() {
console.log("I am " + this.name);
}
};
// call: runs immediately
hero.introduce.call({ name: "Robin" });
// "I am Robin" (runs now!)
// bind: creates new function for later
const robinIntro = hero.introduce.bind({ name: "Robin" });
robinIntro(); // "I am Robin" (runs when you call it)
Real-World Use: Event Handlers
const game = {
score: 0,
addPoint: function() {
this.score++;
console.log("Score: " + this.score);
}
};
// Problem: this becomes the button!
button.onclick = game.addPoint; // Broken đ˘
// Solution: bind locks this to game
button.onclick = game.addPoint.bind(game); // Works! đ
With Pre-set Arguments
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
console.log(double(5)); // 10
console.log(double(8)); // 16
The first argument (2) is now permanently set!
Quick Summary: call vs apply vs bind
graph TD A["Need to change this?"] --> B{Run immediately?} B -->|Yes| C{Have array of args?} C -->|Yes| D["Use apply"] C -->|No| E["Use call"] B -->|No, save for later| F["Use bind"]
| Method | When it Runs | Arguments |
|---|---|---|
call |
Immediately | One by one |
apply |
Immediately | As array |
bind |
Later (returns function) | One by one |
Final Story: The Three Magic Spells đŞ
Imagine you have a magic spell (function) that only works for its owner (this).
call= âCast this spell right now, but pretend this person is the owner!âapply= âSame as call, but ingredients come in a basket (array)!âbind= âCreate a copy of this spell that will always work for this person!â
And remember:
Arrow functions are like spells that donât have an owner. They just use whoever is standing nearby (their parentâs
this).
Youâve Got This! đ
Now you understand:
- â
thischanges based on who calls the function - â
Arrow functions borrow their parentâs
this - â
callandapplylet you choosethistemporarily - â
bindlocksthispermanently in a new function
Go forth and master this! đ
