How to use “setTimeout” to invoke object itself

前端 未结 3 818
心在旅途
心在旅途 2020-12-01 04:37

Why can\'t I use setTimeout in a javascript object?

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.fee         


        
相关标签:
3条回答
  • 2020-12-01 05:13

    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.

    0 讨论(0)
  • 2020-12-01 05:24

    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.

    0 讨论(0)
  • 2020-12-01 05:26

    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);}
    
    0 讨论(0)
提交回复
热议问题