Подтвердить что ты не робот

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

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

    };
}

Спасибо за решение Steve's, теперь он будет работать, если код выглядит следующим образом... потому что 'this' before фактически указывал на функцию в 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);
    }
}
4b9b3361

Ответ 1

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

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 - независимо от того, где они объявлены. Поэтому перемещение кода в отдельную функцию не устранит проблему.

Ответ 2

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

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

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

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.

Ответ 3

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

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

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

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