Why can't I use setTimeout
in a javascript object?
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 ??????
};
}
Thanks for Steve`s Solution, now it will work if the code is as below... because the 'this' before was actually pointing to the function within setTimeOut, it cannot rearch Message.
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);
};
}
But why doesn`t it work if we do this:
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);
}
}
The setTimeout() returns a timeoutID which is a positive integer identifying the timer created as a result of calling the method. The timeoutID can be used to cancel timeout by passing it to the clearTimeout() method.
You can also run setTimeout synchronously with await, promise.
The setTimeout() is a method inside the window object, it calls the specified function or evaluates a JavaScript expression provided as a string after a given time period for only once.
Try replacing this line:
setTimeout('this.feedbackTag.removeChild(info)', 5000);
with these two lines:
var _this = this; setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);
Note:
Never pass setTimeout
a string, as this invokes eval
(which you should only use when necessary). Instead, pass setTimeout
a function reference (this can be an anonymous function).
Finally, always check that the this
keyword is pointing to what you think it points to (see http://www.alistapart.com/articles/getoutbindingsituations).
Addressing Question 2:
I believe that for normal functions, this
is set to the window
object—regardless of where they are declared. So moving the code into a separate function wouldn't fix the problem.
A neater way is to just pass this as an argument to the function being called in the timeout:
function delayRemove(obj) {
setTimeout(function(_this) {
_this.feedbackTag.removeChild(obj);
}, 5000, this);
}
You should really pass obj as an argument as well, just to make sure it is in scope (the number of parameters is unlimited):
function delayRemove(obj) {
setTimeout(function(_this, removeObj) {
_this.feedbackTag.removeChild(removeObj);
}, 5000, this, obj);
}
HTML5 and Node.js extended the setTimeout
function to accept parameters which are passed to your callback function. It has the following method signature.
setTimeout(callback, delay, [param1, param2, ...])
As setTimeout
isn't actually a JavaScript feature your results may vary across browsers. I couldn't find any concrete details of support, however as I said this is in the HTML5 spec.
To answer your last question: "Why doesn`t it work if we do this":
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);
}}
It's not working because you are passing an undefined variable (info
) instead of a defined variable (obj
). Here is the corrected function:
function delayRemove(obj) {
var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(obj); }, 5000);}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With