当前位置:  开发笔记 > 编程语言 > 正文

JavaScript中的setTimeout和"this"

如何解决《JavaScript中的setTimeout和"this"》经验,为你挑选了3个好方法。

我有一个使用该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];
        }
    }
};

Warren.. 50

更优雅的选项是附加.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
    }; 


Dan Lew.. 47

问题是setTimeout()导致javascript使用全局范围.从本质上讲,你是在打电话给method()班级,而不是来自this.相反,你只是告诉setTimeout使用该功能method,没有特定的范围.

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

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



1> Warren..:

更优雅的选项是附加.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
    }; 



2> Dan Lew..:

问题是setTimeout()导致javascript使用全局范围.从本质上讲,你是在打电话给method()班级,而不是来自this.相反,你只是告诉setTimeout使用该功能method,没有特定的范围.

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

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


你是个巫师.

3> Jason..:

this你使用中setTimeOut通过自身的范围界定.var "foo = this;"在t est.prototype.method函数内部创建并使用foo.

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有