JavaScript this Keyword Interview Questions (With Answers)
this is probably the most confusing keyword in JavaScript, and that’s exactly why interviewers ask about it so much.
The good news is that almost every this question can be solved with one rule from the This Keyword article: this depends on how the function is called, not where it’s written. Arrow functions are the only exception.
Keep that in mind, and try to work out each answer yourself before reading the explanation.
1. How does this work inside an object method?
Section titled “1. How does this work inside an object method?”const user = {
firstName: "Riya",
greet() {
console.log(`Hi, I'm ${this.firstName}`);
}
};
user.greet();
Answer: Hi, I'm Riya
In the above example, you can see that:
greetis called as a method, withuseron the left of the dot.- Whatever is on the left of the dot becomes
this. - So
thisisuser, andthis.firstNameis"Riya".
That’s the easy one. Now let’s start breaking it.
2. Why is this undefined when you store a method in a variable?
Section titled “2. Why is this undefined when you store a method in a variable?”const user = {
firstName: "Riya",
greet() {
console.log(`Hi, I'm ${this.firstName}`);
}
};
const greet = user.greet;
greet();
Answer: Hi, I'm undefined (or a TypeError in strict mode)
In the above example, you can see that:
const greet = user.greetcopies only the function. It doesn’t carryuseralong with it.- When we call
greet(), there’s nothing on the left of the dot. - In non-strict mode,
thisfalls back to the global object, which has nofirstName, so we getundefined. - In strict mode,
thisisundefined, sothis.firstNamethrowsTypeError: Cannot read properties of undefined.
Same function, different call, different this.
3. What is this inside a nested object’s method?
Section titled “3. What is this inside a nested object’s method?”const company = {
name: "Acme",
team: {
name: "Frontend",
getName() {
return this.name;
}
}
};
console.log(company.team.getName());
Answer: Frontend
In the above example, you can see that:
getNameis called ascompany.team.getName().- Only the object directly left of the dot counts, and here that’s
company.team. - So
thisisteam, andthis.nameis"Frontend", not"Acme".
4. Why is this undefined in an arrow function method?
Section titled “4. Why is this undefined in an arrow function method?”const user = {
firstName: "Riya",
greet: () => {
console.log(`Hi, I'm ${this.firstName}`);
}
};
user.greet();
Answer: Hi, I'm undefined
Wait, what? We called it as user.greet() this time!
In the above example, you can see that:
greetis an arrow function, and arrow functions don’t have their ownthis.- Instead, they use the
thisfrom the place where they were written. - The object literal
{ ... }doesn’t create a newthis. So the arrow function takesthisfrom the outer code, which isn’tuser. - So
this.firstNameisundefined.
5. Why is this undefined inside a forEach callback?
Section titled “5. Why is this undefined inside a forEach callback?”const user = {
firstName: "Riya",
hobbies: ["coding", "music"],
showHobbies() {
this.hobbies.forEach(function (hobby) {
console.log(`${this.firstName} likes ${hobby}`);
});
}
};
user.showHobbies();
Answer: undefined likes coding and undefined likes music (or a TypeError in strict mode)
In the above example, you can see that:
showHobbiesis called asuser.showHobbies(), so inside it,thisisuser. That’s whythis.hobbiesworks.- But the callback passed to
forEachis a normal function, andforEachcalls it on its own, without anything on the left of the dot. - So inside the callback,
thisis notuseranymore.
The fix is to turn the callback into an arrow function:
showHobbies() {
this.hobbies.forEach((hobby) => {
console.log(`${this.firstName} likes ${hobby}`);
});
}
// Riya likes coding
// Riya likes music
Since the arrow function doesn’t have its own this, it uses the this of showHobbies, which is user. This is exactly the place where arrow functions shine.
6. Why does this get lost in setTimeout, and how do you fix it?
Section titled “6. Why does this get lost in setTimeout, and how do you fix it?”const user = {
firstName: "Riya",
greet() {
console.log(`Hi, I'm ${this.firstName}`);
}
};
setTimeout(user.greet, 1000);
Answer: Hi, I'm undefined
In the above example, you can see that:
- We passed
user.greettosetTimeout. That passes only the function, notuser. - A second later,
setTimeoutcalls it on its own, sothisis lost.
There are two common fixes:
// Fix 1: wrap it in an arrow function
setTimeout(() => user.greet(), 1000);
// Fix 2: bind this to user
setTimeout(user.greet.bind(user), 1000);
Both print Hi, I'm Riya. In the first fix, greet is called as user.greet() again. In the second, bind creates a new function with this locked to user.
7. What’s the difference between call, apply and bind?
Section titled “7. What’s the difference between call, apply and bind?”function introduce(city, country) {
console.log(`${this.firstName} from ${city}, ${country}`);
}
const person = { firstName: "Aman" };
introduce.call(person, "Delhi", "India"); // Aman from Delhi, India
introduce.apply(person, ["Delhi", "India"]); // Aman from Delhi, India
const introduceAman = introduce.bind(person, "Delhi", "India");
introduceAman(); // Aman from Delhi, India
In the above example, you can see that:
- All three let you choose what
thisshould be. Here, it’sperson. callruns the function right away and takes arguments one by one.applyalso runs it right away, but takes the arguments as an array.binddoes not run the function. It returns a new function withthislocked in, which you can call later.
8. Can you bind a function twice in JavaScript?
Section titled “8. Can you bind a function twice in JavaScript?”function show() {
console.log(this.firstName);
}
const showRiya = show.bind({ firstName: "Riya" });
const showAman = showRiya.bind({ firstName: "Aman" });
showAman();
Answer: Riya
Hmm, you may be wondering why the second bind didn’t change it to Aman.
In the above example, you can see that:
show.bind({ firstName: "Riya" })creates a new function withthispermanently locked to the Riya object.- Binding that function again doesn’t unlock it.
bindcan’t override athisthat’s already been bound. - So no matter how you call
showAman,thisstays the Riya object.
The same applies to call and apply. showRiya.call({ firstName: "Aman" }) still prints Riya.
9. What happens if you forget new with a constructor function?
Section titled “9. What happens if you forget new with a constructor function?”function User(firstName) {
this.firstName = firstName;
}
const user1 = new User("Aman");
const user2 = User("Riya");
console.log(user1.firstName);
console.log(user2);
Answer: Aman, then undefined (or a TypeError in strict mode)
In the above example, you can see that:
- When you call a function with
new, JavaScript creates a brand-new empty object, setsthisto that object, and returns it at the end. - So
user1is a new object withfirstNameset to"Aman". User("Riya")is called withoutnew. It’s just a normal function call, sothisisn’t a new object.- The function doesn’t return anything, so
user2isundefined. - Even worse, in non-strict mode
thisis the global object, sothis.firstName = "Riya"quietly creates a global variable. In strict mode, it throws aTypeErrorinstead.
That’s why forgetting new is such a sneaky bug.
🧵 Wrapping It Up
Section titled “🧵 Wrapping It Up”You practiced how to:
- Find
thisby looking at what’s left of the dot - Spot when
thisgets lost, like when you copy a method or pass it as a callback - Know when arrow functions help and when they hurt
- Use
call,applyandbind, and know that a bound function can’t be bound again - Explain what
newdoes and what happens when you forget it
For any this question, look at the call, not the function. If it’s an arrow function, look at where it was written. Otherwise, look at how it was called.