setTimeout和JavaScript中的“this”

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

问题是setTimeout()导致javascript使用全局范围。 本质上,你调用method()类,但不是从“this”。 相反,你只是告诉setTimeout使用函数“方法”,没有特别的范围。

为了解决这个问题,你可以把函数调用包装在另一个引用正确variables的函数调用中。 它看起来像这样:

 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()在方法的范围之内。

当您需要将parameter passing给setTimeout方法时,此问题变得更加复杂,因为IE不支持超过两个setTimeout参数。 在这种情况下,你需要阅读closures 。

另外,作为一个旁注,你正在设置一个无限循环,因为method()总是调用method()。

更优雅的select是将.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中使用的“this”是通过自身进行的作用域。 创build一个var“foo = this;” 在你的test.prototype.method函数里面,改用foo。

我得到一个错误,说method2是未定义的

是的,当你从它的所有者中切掉this.method,并把这个函数单独传递给setTimeout时,你失去了设置'this'的关联,所以method()中的'this'等于全局对象'window'。

看到这个答案的解释,“这个”在JavaScript中实际工作的惊人的方式。