如何使用“setTimeout”来调用对象本身

时间:2022-07-30 16:58:07

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

为什么我不能在javascript对象中使用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);

        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.

感谢Steve的解决方案,现在如果代码如下所示它将起作用...因为之前'this'实际指向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);

    };
}

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);
    }
}

3 个解决方案

#1


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).

永远不要将setTimeout传递给字符串,因为这会调用eval(您只应在必要时使用它)。相反,传递setTimeout一个函数引用(这可以是一个匿名函数)。

Finally, always check that the this keyword is pointing to what you think it points to (see http://www.alistapart.com/articles/getoutbindingsituations).

最后,请始终检查this关键字是否指向您认为指向的内容(请参阅http://www.alistapart.com/articles/getoutbindingsituations)。

Addressing Question 2:

解决问题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.

我相信对于普通函数,它被设置为窗口对象 - 无论它们在何处被声明。因此,将代码移动到单独的函数中无法解决问题。

#2


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):

你应该将obj作为参数传递,只是为了确保它在范围内(参数的数量是无限的):

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.

HTML5和Node.js扩展了setTimeout函数以接受传递给回调函数的参数。它具有以下方法签名。

setTimeout(callback, delay, [param1, param2, ...])

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.

由于setTimeout实际上不是JavaScript功能,因此您的结果可能因浏览器而异。我找不到任何具体的支持细节,但正如我所说,这是HTML5规范。

#3


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:

它不起作用,因为您传递的是未定义的变量(info)而不是已定义的变量(obj)。这是更正后的功能:

function delayRemove(obj) {
var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(obj); }, 5000);}

#1


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).

永远不要将setTimeout传递给字符串,因为这会调用eval(您只应在必要时使用它)。相反,传递setTimeout一个函数引用(这可以是一个匿名函数)。

Finally, always check that the this keyword is pointing to what you think it points to (see http://www.alistapart.com/articles/getoutbindingsituations).

最后,请始终检查this关键字是否指向您认为指向的内容(请参阅http://www.alistapart.com/articles/getoutbindingsituations)。

Addressing Question 2:

解决问题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.

我相信对于普通函数,它被设置为窗口对象 - 无论它们在何处被声明。因此,将代码移动到单独的函数中无法解决问题。

#2


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):

你应该将obj作为参数传递,只是为了确保它在范围内(参数的数量是无限的):

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.

HTML5和Node.js扩展了setTimeout函数以接受传递给回调函数的参数。它具有以下方法签名。

setTimeout(callback, delay, [param1, param2, ...])

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.

由于setTimeout实际上不是JavaScript功能,因此您的结果可能因浏览器而异。我找不到任何具体的支持细节,但正如我所说,这是HTML5规范。

#3


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:

它不起作用,因为您传递的是未定义的变量(info)而不是已定义的变量(obj)。这是更正后的功能:

function delayRemove(obj) {
var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(obj); }, 5000);}