Como usar o "setTimeout" para invocar o próprio objeto
-
12-09-2019 - |
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);
}
}
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);}