Javascript setInterval和`this`解决方案

Pab*_*blo 61 javascript this setinterval

我需要this从我的setInterval处理程序访问

prefs: null,
startup : function()
    {
        // init prefs
        ...
        this.retrieve_rate();
        this.intervalID = setInterval(this.retrieve_rate, this.INTERVAL);
    },

retrieve_rate : function()
    {
        var ajax = null;
        ajax = new XMLHttpRequest();
        ajax.open('GET', 'http://xyz.com', true);
        ajax.onload = function()
        {
            // access prefs here
        }
    }
Run Code Online (Sandbox Code Playgroud)

我如何访问this.prefs ajax.onload

Ant*_*nes 86

setInterval行应如下所示: -

 this.intervalID = setInterval(
     (function(self) {         //Self-executing func which takes 'this' as self
         return function() {   //Return a function in the context of 'self'
             self.retrieve_rate(); //Thing you wanted to run as non-window 'this'
         }
     })(this),
     this.INTERVAL     //normal interval, 'this' scope not impacted here.
 ); 
Run Code Online (Sandbox Code Playgroud)

编辑:同样的原则适用于" onload".在这种情况下,它对于"外部"代码的共同作用很少,它只是设置请求然后发送它.在这种情况下,额外的开销和上述代码中的附加功能是不必要的.您的retrieve_rate看起来应该更像这样: -

retrieve_rate : function()
{
    var self = this;
    var ajax = new XMLHttpRequest();
    ajax.open('GET', 'http://xyz.com', true);
    ajax.onreadystatechanged= function()
    {
        if (ajax.readyState == 4 && ajax.status == 200)
        {
            // prefs available as self.prefs
        }
    }
    ajax.send(null);
}
Run Code Online (Sandbox Code Playgroud)


Nec*_*hin 80

this.intervalID = setInterval(this.retrieve_rate.bind(this), this.INTERVAL);
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的解决方案.接受的解决方案似乎需要不必要的更多代码. (12认同)
  • 但是这种方法有一个缺点.最有可能的是,它不适用于旧版本的IE (5认同)
  • @Nechehin 值得注意。但它仍然是一个更干净的解决方案。 (2认同)
  • 从 IE9 开始就支持它,所以对我来说这是一个干净的解决方案。 (2认同)
  • 如果需要对IE8的支持,并且正在使用[Underscore.js](http://underscorejs.org),则可以使用[`_.bind`](http://underscorejs.org/#bind) :`this.intervalID = setInterval(_。bind(this.retrieve_rate,this),this.INTERVAL);` (2认同)

Joe*_*ore 18

默认行为setInterval是绑定到全局上下文.您可以通过保存当前上下文的副本来调用成员函数.在retrieve_rate内部,this变量将正确绑定到原始上下文.这是您的代码的样子:

var self = this;
this.intervalID = setInterval(
    function() { self.retrieve_rate(); },
    this.INTERVAL);
Run Code Online (Sandbox Code Playgroud)

额外提示:对于普通函数引用(与具有成员函数的对象引用相对),您可以使用JavaScript callapply方法更改上下文.


Mar*_*ark 12

随着浏览器支持的改进,=>现在可以使用EcmaScript 6增强功能(箭头方法)来保持this正确的时间.

startup : function()
    {
        // init prefs
        ...
        this.retrieve_rate();
        this.intervalID = setInterval( () => this.retrieve_rate(), this.INTERVAL);
    },
Run Code Online (Sandbox Code Playgroud)

使用=>方法保留thisretrieve_rate()由间隔调用.不需要时髦的自我或传递this参数


Dan*_*lov 8

window.setInterval(function(){console.log(this)}.bind(this), 100)

这在javascript中是合法的并且节省了大量代码:)