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