代码之家  ›  专栏  ›  技术社区  ›  Christian Studer delphist

在javascript中设置超时和“this”

  •  29
  • Christian Studer delphist  · 技术社区  · 5 年前

    我有一个方法使用 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 回复  |  直到 6 年前
        1
  •  45
  •   Daniel Lew    7 年前

    问题是 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 可以是 因为 callMethod() 在方法的范围内。

    当需要将参数传递给 设置超时 方法,因为IE不支持两个以上的参数 设置超时 . 如果那样的话,你就得好好读一读 closures .

    另外,作为旁注,你将自己设置为一个无限循环,因为 方法() 总是呼叫 方法() .

        2
  •  47
  •       11 年前

    更优雅的选择是附加 .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
        }; 
    
        3
  •  7
  •   Ryan Rinaldi    7 年前

    这个 this 你用过 setTimeOut 正在通过自身确定范围。创建一个 var "foo = this;" 在你的T里面 est.prototype.method 功能和用途 foo 相反。

        4
  •  0
  •   Jordi    7 年前

    我得到一个错误,说方法2未定义

    是的,当你切的时候 this.method 从其所有者并将函数单独传递给 setTimeout ,您将失去设置的关联 this 如此 在里面 method() 等于全局对象 window .

    this answer 为了解释这个令人惊讶的方式 实际上在javascript中工作。

        5
  •  0
  •       6 年前

    在ES6中,你可以这样做

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