Pergunta

Por que não posso usar setTimeout em um objeto javascript?

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.feedbackTag = document.getElementById('feedbackMessages');

    this.addInfo = function (message) {
        var info = this.messageFactory.createInfo(message); // create a div
        this.feedbackTag.appendChild(info);

        setTimeout('this.feedbackTag.removeChild(info)', 5000);
        // why in here, it complain this.feedbacktag is undefined ??????

    };
}

Obrigado por Steve Solução, agora ele vai funcionar se o código é como abaixo...porque o 'isso' antes era, na verdade, apontando para a função dentro de setTimeOut, ele não pode rearch Mensagem.

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.feedbackTag = document.getElementById('feedbackMessages');

    this.addInfo = function (message) {
        var info = this.messageFactory.createInfo(message); // create a div
        this.feedbackTag.appendChild(info);

        var _this = this;
        setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);

    };
}

Mas por que não trabalhar, se fazer isso:

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.feedbackTag = document.getElementById('feedbackMessages');
    // public function
    this.addInfo = function (message) {
        var info = this.messageFactory.createInfo(message); // create a div
        this.feedbackTag.appendChild(info);

        delayRemove(info);

    };
    // private function
    function delayRemove(obj) {
        var _this = this;
        setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);
    }
}
Foi útil?

Solução

Tente substituir esta linha:

setTimeout('this.feedbackTag.removeChild(info)', 5000);

Com estas duas linhas:

var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);

Observação:

Nunca passa setTimeout uma string, como isso invoca eval (que você deve usar apenas quando necessário). Em vez disso, passe setTimeout uma referência de função (essa pode ser uma função anônima).

Finalmente, sempre verifique se o this A palavra -chave está apontando para o que você acha que aponta (veja http://www.alistapart.com/articles/getoutbindingsituations).

Abordando a pergunta 2:

Eu acredito nisso para funções normais, this está definido para o window Objeto - indefinido de onde eles são declarados. Portanto, mover o código para uma função separada não resolveria o problema.

Outras dicas

De uma forma sucinta, é só passar este como um argumento para a função a ser chamada em tempo de espera:

function delayRemove(obj) {
  setTimeout(function(_this) {
      _this.feedbackTag.removeChild(obj);
    }, 5000, this);
}

Você deve realmente passar obj como um argumento bem, só para ter certeza que está no escopo (o número de parâmetros é ilimitado):

function delayRemove(obj) {
  setTimeout(function(_this, removeObj) {
      _this.feedbackTag.removeChild(removeObj);
    }, 5000, this, obj);
}

HTML5 e Node.js prorrogado o setTimeout função para aceitar parâmetros que são passados para a função de chamada de retorno.Ele tem a seguinte assinatura de método.

setTimeout(callback, delay, [param1, param2, ...])

Como setTimeout não é realmente um recurso de JavaScript seus resultados podem variar entre os navegadores.Eu não poderia encontrar qualquer detalhes concretos de apoio, no entanto, como eu disse este é o HTML5 spec.

Para responder sua última pergunta: "Por que não funciona se fizermos isso":

Message = function () {

...
...        

this.messageFactory = ...
this.feedbackTag = document.getElementById('feedbackMessages');
// public function
this.addInfo = function (message) {
    var info = this.messageFactory.createInfo(message); // create a div
    this.feedbackTag.appendChild(info);

    delayRemove(info);

};
// private function
function delayRemove(obj) {
    var _this = this;
    setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);
}}

Não está funcionando porque você está passando uma variável indefinida (info) em vez de uma variável definida (obj). Aqui está a função corrigida:

function delayRemove(obj) {
var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(obj); }, 5000);}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top