Как использовать "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);
}
}
Ответы
Ответ 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);}