#113 Losing this

easy
javascript

In JavaScript, the value of this can be "lost" when a method is passed as a callback or used separately from its object. This often happens with functions like setTimeout.

Consider the following code:

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(user.sayHi, 1000); // Hello, undefined!

Explain why the output of the above code is undefined instead of "John". Also, Explain what can we do to ensure that this inside sayHi refers to the user object, even when passed to setTimeout.

When user.sayHi is passed to setTimeout, it is detached from the user object. Therefore, when setTimeout calls this function, it does so without any context, causing this to be undefined.

Solution: Here are a few ways to fix this issue:

1. Using bind:

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(user.sayHi.bind(user), 1000); // Hello, John!

2. Using an arrow function:

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(() => user.sayHi(), 1000); // Hello, John!

3. Using a wrapper function:

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(function() {
  user.sayHi();
}, 1000); // Hello, John!