views:

1080

answers:

1

hi, the code below..why i can not use the setTimeOut within an 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 it doesn`t 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);
    }
}
+7  A: 

Try replacing the line:

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

...with the following 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 points to what you think it is (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.

Steve

Steve Harrison
wow...it works...why have to use the 'this' like that....
shrimpy
Wouldn't that introduce a memory leak?
tsilb
@shrimpy: It's a complex problem, but this article describes it quite well: http://www.alistapart.com/articles/getoutbindingsituations. Basically, "this" doesn't point to the Message class inside the anonymous function. To fix this problem, we create a variable (I called it "_this"), make it point to the correct Message class, and then use this variable when we want to reference the class inside the anonymous function.
Steve Harrison
@tslib: In what way? This workaround is quite common. If you're worried that the anonymous function is going to keep things tied up, I'm pretty sure that it will be zapped by the Garbage Collector as soon as "setTimeout" has finished with it.
Steve Harrison
@tsilb: Whoops—I spelt your username incorrectly in my previous comment! Sorry!
Steve Harrison
Love you Steve.
Senica Gonzalez