This is explained in documentation:
Code executed by setInterval()
runs in a Separate Execution context than the Function from which it was called. As a consequence, the this
keyword for the called Function is set to the window
(or global) Object, it is not the same as the this
value for the Function that called setTimeout
.
In free translation:
The code executed by setInterval
runs in a separate context from the function where it was called. Consequently, the this
call function is set to the object window
(or global), and is not the same this
of the function that called setTimeout
.
We can see this behavior changing your example a little:
var x = 0, id = 0;
function Pessoa(){
this.idade = 0;
id = setInterval(function() {
this.idade++;
console.log(this == window, this.idade); // true NaN
// só pra não ficar executando eternamente
if (x++ >= 2) clearInterval(id);
}, 1000);
}
new Pessoa();
Spinning in a browser, the this
will equal window
, as stated in the documentation. And how window.idade
was not defined (because on the line this.idade = 0
, the this
refers to the Pessoa
), then within the function the value of this.idade
is undefined
, since he’s trying to catch window.idade
.
Already using Arrow Function, the this
is not amended in this way, and refers to the Pessoa
:
var x = 0, id = 0;
function Pessoa(){
this.idade = 0;
id = setInterval(() => {
this.idade++;
console.log(this == window, this, this.idade); // false { "idade": valor } valor da idade
// só pra não ficar executando eternamente
if (x++ >= 2) clearInterval(id);
}, 1000);
}
new Pessoa();
And using bind
also works, because the return of bind
is a function equal to the original, but with the this
set to the given value:
var x = 0, id = 0;
function Pessoa(){
this.idade = 0;
id = setInterval(function() {
this.idade++;
console.log(this == window, this, this.idade); // false { "idade": valor } valor da idade
// só pra não ficar executando eternamente
if (x++ >= 2) clearInterval(id);
}.bind(this), 1000);
}
new Pessoa();
In the case, .bind(this)
is out of anonymous function, so at that point the this
refers to Pessoa
. That is, the bind
returned a function equal to the anonymous function, but with the this
set to the Pessoa
.
What confuses in the above cases is that every moment the this
can represent a different thing. It’s really confusing: