Boa noite, Cauê!
O this
do JavaScript é um assunto complexo! Eu recomendo muito ler, com paciência, os capítulos 1 e 2 do livro You Don't Know JS: this & Object Prototypes (em inglês). Ele entra bem a fundo no assunto, explicando primeiro o que this
não é e depois o que ele é e como funciona.
Eu vou tentar explicar de forma simples o que acontece no seu código de exemplo.
Normalmente, o valor de this
é atribuído no momento em que a função é chamada, recebendo o contexto em que foi chamada (e não quando ela é definida, como normalmente imaginamos. Não é assim que costuma funcionar em outras linguagens). Funções de callback, como a que você definiu dentro de setInterval
, são chamadas posteriormente, fora do contexto da classe que você está definindo. É como se "perdessem" a ligação com o this
do objeto sendo criado. (Na verdade, não se perde a ligação; nunca houve essa ligação. Mas eu acho mais fácil raciocinar assim :)
O que podemos fazer? Uma forma é fazer com que a função "leve" o this
do objeto com ela, usando o método bind
:
setInterval(function () {
console.log(++this._segundos);
}.bind(this), 1000);
Agora, lembra que eu disse que "normalmente" funciona assim? Isso porque com as arrow functions as coisas funcionam de forma diferente. Elas não são apenas uma forma mais curta de se escrever funções. Elas também tem uma maneira diferente de lidar com o this
. Elas capturam o this
do escopo onde foram definidas. No exemplo a seguir, a arrow function captura o this
do lugar onde setInterval
foi chamado, no caso o objeto sendo criado por new Relogio
:
setInterval( () => console.log(++this._segundos), 1000);
O resultado final acaba sendo o mesmo do exemplo anterior.
Espero que a explicação tenha feito algum sentido, Cauê! Como eu disse, o funcionamento do this
não é simples. E eu realmente recomendo a leitura que eu citei; ela é bem detalhada e esclarece bastante o assunto. Até logo!