JavaScript 中的 setTimeout 和“this”

IT技术 javascript
2021-02-08 21:46:56

我有一个使用该setTimeout函数并调用另一个方法的方法。在初始加载方法 2 工作正常。但是,超时后,我收到一条错误消息,指出method2未定义。我在这里做错了什么?

前任:

test.prototype.method = function()
{
    //method2 returns image based on the id passed
    this.method2('useSomeElement').src = "http://www.some.url";
    timeDelay = window.setTimeout(this.method, 5000);
};

test.prototype.method2 = function(name) {
    for (var i = 0; i < document.images.length; i++) {
        if (document.images[i].id.indexOf(name) > 1) {
            return document.images[i];
        }
    }
};
5个回答

一个更优雅的选择是附加.bind(this)到函数的末尾。例如:

    setTimeout(function() {
        this.foo();
    }.bind(this), 1000);
//   ^^^^^^^^^^^ <- fix context

所以OP问题的答案可能是:

    test.prototype.method = function()
    {
        //method2 returns image based on the id passed
        this.method2('useSomeElement').src = "http://www.some.url";
        timeDelay = window.setTimeout(this.method.bind(this), 5000);
        //                                       ^^^^^^^^^^^ <- fix context
    }; 

问题是setTimeout()导致 javascript 使用全局范围。本质上,您是在调用method()类,而不是从this. 相反,您只是告诉setTimeout使用method没有特定范围的 function

要解决此问题,您可以将函数调用包装在另一个引用正确变量的函数调用中。它看起来像这样:

test.protoype.method = function()
{
    var that = this;

    //method2 returns image based on the id passed
    this.method2('useSomeElement').src = "http://www.some.url";

    var callMethod = function()
    {
        that.method();
    }

    timeDelay = window.setTimeout(callMethod, 5000);
};

that可能是this因为callMethod()在方法的范围内。

当您需要向setTimeout方法传递参数时,这个问题会变得更加复杂,因为 IE 不支持setTimeout. 在这种情况下,您需要阅读闭包

此外,作为旁注,您将自己设置为无限循环,因为method()总是调用method().

这是一篇关于闭包的优秀文章,链接中有实际示例!谢谢!
2021-03-16 21:46:56
嘿,这适用于 mozilla,但不适用于 ie!任何线索?图像也不会循环,一旦到达最后一张图像就会停止
2021-04-09 21:46:56

this你所使用setTimeout的通过本身作用域。var _this = this;在您的test.prototype.method函数内部创建一个并使用_this

“通过自身进行范围界定”是什么意思?
2021-03-19 21:46:56

在es6中你可以这样做

window.setTimeout(() => {
    this.foo();
}, 1000);   

我收到一条错误消息,指出 method2 未定义

是的,当你this.method从它的所有者那里切下来并将函数单独传递给 时setTimeout,你失去了设置的关联this,所以thisinmethod()等于全局对象window

请参阅此答案以了解thisJavaScript 中实际工作的惊人方式