Escopo no window.setTimeout

Sim, mais um micropost. Agora para falar de um detalhe relacionado a esta função do JavaScript que vez ou outra causa uma dor de cabeça na hora de usar.

O problema

Imagine que você tem o seguinte código:

var MeuObjeto = function () {
            var _intervalo = 1000;
            this.Rodar = function () {
                alert("rodou!");
                window.setTimeout(function () { this.Rodar() }, _intervalo);
            }
        }

Ao que parece, tudo certo, certo? Errado!

Quando chamarmos

new MeuObjeto().Rodar();

você perceberá que após a primeira execução, as demais chamadas que deveriam ocorrer a cada 1 segundo não acontecerão e, dependendo do navegador, você verá uma mensagem de erro.

Causa

Durante a utilização do window.setTimeout, o escopo interno do método em questão é o do objeto window e não MeuObjeto como você (e o intellisense do Visual Studio 2010) poderia imaginar.

Solução

Ponteiro. (oh yeah!)

var MeuObjeto = function () {
            var _intervalo = 1000;
            var _eu = this;
            this.Rodar = function () {
                alert("rodou!");
                window.setTimeout(function () { _eu.Rodar() }, _intervalo);
            }
        }

Note que adicionamos uma variável nova no escopo do objeto MeuObjeto a qual contém uma referência para o objeto em si. Esta variável se torna visivel para o método que será chamado no window.setTimeout permitindo o acesso direto ao escopo desejado.

Deixe um comentário