Как использовать «setTimeout» для вызова самого объекта

StackOverflow https://stackoverflow.com/questions/1101668

  •  12-09-2019
  •  | 
  •  

Вопрос

Почему я не могу использовать setTimeout в объекте 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 ??????

    };
}

Спасибо за решение Стива, теперь оно будет работать, если код такой, как показано ниже...поскольку «это» раньше фактически указывало на функцию внутри setTimeOut, оно не может найти сообщение.

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);

    };
}

Но почему это не сработает, если мы сделаем так:

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);
    }
}
Это было полезно?

Решение

Попробуйте заменить эту строку:

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

с этими двумя строками:

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

Примечание:

Никогда не проходите setTimeout строка, поскольку это вызывает eval (который следует использовать только при необходимости).Вместо этого пройдите setTimeout ссылка на функцию (это может быть анонимная функция).

Наконец, всегда проверяйте, что this Ключевое слово указывает на то, на что, по вашему мнению, оно указывает (см. http://www.alistapart.com/articles/getoutbindingsituations).

Решение вопроса 2:

Я считаю, что для нормальных функций this установлен на window объект — независимо от того, где они объявлены.Таким образом, перемещение кода в отдельную функцию не решит проблему.

Другие советы

Более аккуратный способ — просто пройти этот в качестве аргумента функции, вызываемой по таймауту:

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

Тебе действительно стоит пройти объект в качестве аргумента, просто чтобы убедиться, что он находится в области видимости (количество параметров не ограничено):

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

HTML5 и Node.js расширили setTimeout функция для приема параметров, которые передаются в вашу функцию обратного вызова.Он имеет следующую сигнатуру метода.

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

Как setTimeout на самом деле это не функция JavaScript ваши результаты могут различаться в разных браузерах.Я не смог найти каких-либо конкретных подробностей о поддержке, однако, как я уже сказал, это предусмотрено в спецификации HTML5.

Чтобы ответить на ваш последний вопрос:«Почему это не сработает, если мы сделаем это»:

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);
}}

Это не работает, потому что вы передаете неопределенную переменную (info) вместо определенной переменной (obj).Вот исправленная функция:

function delayRemove(obj) {
var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(obj); }, 5000);}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top