Skip to content

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:

  1. greet is called as a method, with user on the left of the dot.
  2. Whatever is on the left of the dot becomes this.
  3. So this is user, and this.firstName is "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:

  1. const greet = user.greet copies only the function. It doesn’t carry user along with it.
  2. When we call greet(), there’s nothing on the left of the dot.
  3. In non-strict mode, this falls back to the global object, which has no firstName, so we get undefined.
  4. In strict mode, this is undefined, so this.firstName throws TypeError: 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:

  1. getName is called as company.team.getName().
  2. Only the object directly left of the dot counts, and here that’s company.team.
  3. So this is team, and this.name is "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:

  1. greet is an arrow function, and arrow functions don’t have their own this.
  2. Instead, they use the this from the place where they were written.
  3. The object literal { ... } doesn’t create a new this. So the arrow function takes this from the outer code, which isn’t user.
  4. So this.firstName is undefined.

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:

  1. showHobbies is called as user.showHobbies(), so inside it, this is user. That’s why this.hobbies works.
  2. But the callback passed to forEach is a normal function, and forEach calls it on its own, without anything on the left of the dot.
  3. So inside the callback, this is not user anymore.

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:

  1. We passed user.greet to setTimeout. That passes only the function, not user.
  2. A second later, setTimeout calls it on its own, so this is 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:

  1. All three let you choose what this should be. Here, it’s person.
  2. call runs the function right away and takes arguments one by one.
  3. apply also runs it right away, but takes the arguments as an array.
  4. bind does not run the function. It returns a new function with this locked 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:

  1. show.bind({ firstName: "Riya" }) creates a new function with this permanently locked to the Riya object.
  2. Binding that function again doesn’t unlock it. bind can’t override a this that’s already been bound.
  3. So no matter how you call showAman, this stays 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:

  1. When you call a function with new, JavaScript creates a brand-new empty object, sets this to that object, and returns it at the end.
  2. So user1 is a new object with firstName set to "Aman".
  3. User("Riya") is called without new. It’s just a normal function call, so this isn’t a new object.
  4. The function doesn’t return anything, so user2 is undefined.
  5. Even worse, in non-strict mode this is the global object, so this.firstName = "Riya" quietly creates a global variable. In strict mode, it throws a TypeError instead.

That’s why forgetting new is such a sneaky bug.

You practiced how to:

  • Find this by looking at what’s left of the dot
  • Spot when this gets lost, like when you copy a method or pass it as a callback
  • Know when arrow functions help and when they hurt
  • Use call, apply and bind, and know that a bound function can’t be bound again
  • Explain what new does 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.