You're conflating variables and objects.
After this...
let user = {
firstName: "John",
sayHi() {
alert(`Hello, ${this.firstName}!`);
}
};
You have a variable called user
, containing an object. But the object is not the variable, and the variable is not the object. If you were to run user = null
, the object would still exist, until garbage collected.
Next, you run
let sayHi = user.sayHi.bind(user);
Now you have another variable, containing a bound function. The function is bound to the object currently sitting in user
, but it has nothing to do with the user
variable, except that you can still reach through that variable to manipulate the object (ie user.firstName = "bob"
). The variable still points to the object created above.
At this point, you could run user = null
and the function sayHi
would still have a function, still bound to the object, which will no longer be garbage collected because there is an active reference to it. You're reassigning the variable, but not removing/replacing the object to which it points.
Later, when you run this...
user = {
sayHi() { alert("Another user in setTimeout!"); }
};
This is no different than running user = null
. The variable sayHi
still holds the old function, still bound to the old object. The variable user
is no longer relevant to the variable sayHi
in any way. They contain two unrelated objects.