Chapter 07 β The this Keyword
π Definition
this refers to the execution context β the object that is currently calling the function.
π Explanation
The value of this is determined by how a function is called, not where it is defined (with the major exception of arrow functions).
The 5 Binding Rules
| # | Binding | Trigger | this is⦠|
|---|---|---|---|
| 1 | Method call | obj.fn() |
obj |
| 2 | Plain call | fn() |
undefined (strict) / globalThis (sloppy) |
| 3 | Constructor | new Fn() |
The new instance |
| 4 | Explicit | fn.call(ctx) / apply / bind |
ctx |
| 5 | Arrow function | Any | Lexically inherited from enclosing scope |
π» Code Example β Method vs Plain Call
const user = {
name: "Soumya",
greet() { return `Hi, ${this.name}`; },
};
user.greet(); // "Hi, Soumya"
const ref = user.greet;
ref(); // "Hi, undefined" β `this` is lostπ» Code Example β Constructor
function Animal(name) {
this.name = name;
}
Animal.prototype.bark = function () {
return `${this.name} barks`;
};
const dog = new Animal("Rex");
dog.bark(); // "Rex barks"π» Code Example β call, apply, bind
function intro(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
const user = { name: "Soumya" };
intro.call(user, "Hi", "!"); // "Hi, Soumya!"
intro.apply(user, ["Hello", "."]); // "Hello, Soumya."
const bound = intro.bind(user, "Hey");
bound("?"); // "Hey, Soumya?"| Method | Calls immediately? | Args |
|---|---|---|
call |
β | individually |
apply |
β | as an array |
bind |
β (returns new fn) | individually (partial application) |
π» Code Example β Arrow Functions Inherit this
class Timer {
constructor() {
this.seconds = 0;
}
startBroken() {
setInterval(function () {
this.seconds++; // β this is undefined / globalThis
}, 1000);
}
startFixed() {
setInterval(() => {
this.seconds++; // β
arrow inherits `this` from method
console.log(this.seconds);
}, 1000);
}
}π» Code Example β this in Event Handlers
const button = document.querySelector("button");
// Regular function β `this` is the button DOM element
button.addEventListener("click", function () {
console.log(this); // <button>
});
// Arrow β `this` is the surrounding scope
button.addEventListener("click", () => {
console.log(this); // window / undefined in module
});π» Code Example β Class Methods Need Binding
// React class component (legacy)
class Counter extends React.Component {
constructor() {
super();
this.state = { count: 0 };
this.handleClick = this.handleClick.bind(this); // β
required
}
handleClick() {
this.setState({ count: this.state.count + 1 });
}
render() {
return <button onClick={this.handleClick}>{this.state.count}</button>;
}
}π Real-World Impact
- React functional components + hooks completely avoid this whole mess.
- Always prefer arrow functions for callbacks that need to "see" the surrounding
this. - Use
bindwhen passing methods as callbacks if you can't change to an arrow.
π― Likely Interview Questions
- What is
this? - Difference between
call,apply, andbind? - What's
thisinside an arrow function? β Inherited from the enclosing lexical scope; arrow functions have no ownthis. - Output prediction:
const obj = { val: 42, arrow: () => this.val, method() { return this.val; }, }; obj.arrow(); // undefined β arrow's this is module/global obj.method(); // 42 β method's this is obj