Javascript setInterval和'this'解决方案
我需要从我的Javascript setInterval和'this'解决方案,javascript,this,setinterval,Javascript,This,Setinterval,我需要从我的setInterval处理程序访问此 prefs: null, startup : function() { // init prefs ... this.retrieve_rate(); this.intervalID = setInterval(this.retrieve_rate, this.INTERVAL); }, retrieve_rate : function() {
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
}
}
如何在
ajax.onload
中访问此.prefs?这不是美容解决方案,但它是常用的:
var self = this;
var ajax = null;
//...
ajax.onload = function() {
self.prefs....;
}
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.
);
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);
}
编辑:相同的原则适用于“onload
”。在这种情况下,“外部”代码通常很少做什么,它只是设置请求,然后发送请求。在这种情况下,上述代码中附加函数的额外开销是不必要的。您的检索率应该如下所示:-
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.
);
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);
}
setInterval
的默认行为是绑定到全局上下文。您可以通过保存当前上下文的副本来调用成员函数。在retrieve_rate内,此
变量将正确绑定到原始上下文。下面是您的代码的外观:
var self = this;
this.intervalID = setInterval(
function() { self.retrieve_rate(); },
this.INTERVAL);
额外提示:对于普通函数引用(与具有成员函数的对象引用相反),您可以使用JavaScript的
调用
或应用
方法更改上下文。这将是最干净的解决方案,由于大多数情况下,您实际上希望为连续的方法调用切换此上下文:
this.intervalID = setInterval(this.retrieve_rate.bind(this), this.INTERVAL);
此外,更容易掌握的概念
// store scope reference for our delegating method
var that = this;
setInterval(function() {
// this would be changed here because of method scope,
// but we still have a reference to that
OURMETHODNAME.call(that);
}, 200);
随着浏览器支持的改进,现在可以很好地使用,以正确地保留
此
startup : function()
{
// init prefs
...
this.retrieve_rate();
this.intervalID = setInterval( () => this.retrieve_rate(), this.INTERVAL);
},
当间隔调用retrieve\u rate()
时,使用=>方法保留此
。不需要在parameters.setInterval(function(){console.log(this)}.bind(this),100)中使用funky self或传递this
这在javascript中是合法的,可以保存大量代码:)在现代浏览器中,setInterval方法允许在计时器过期后将附加参数传递给func指定的函数 因此,一个可能的解决方案可以是:
this.intervalID = setInterval(function (self) {
self.retrieve_rate();
}, this.INTERVAL, this);
演示:
var-timerId;
document.querySelector(“#clickMe”).addEventListener('click',函数(e){
timerId=setInterval(函数(自身){
self.textContent=self.textContent.slice(0,-1);
if(self.textContent.length==0){
清除间隔(timerId);
self.textContent='end..';
}
},250,这个);
})
单击我
此
在传递给setInterval
的函数中,将引用全局对象。你是说context.retrieve\u rate
而不是this.retrieve\u rate
?这是朝着正确的方向发展的,不需要将上下文作为参数传递。@Matthew,Anthony那么我如何从onload访问它呢?尝试了这个.prefs,但没有成功…不客气,Matthew,顺便说一下,您不需要使用调用,上下文。检索率()
就足够了,因为您有一个基本对象(上下文。
),再次感谢@Anthony和@CMS.)当闭包起作用时,很容易变得不必要的“聪明”。问题是setInterval
如何调用retrieve\u rate
函数,方法中的这个
值指的是全局对象…我本来打算这样做的,但后来我想起了这种模式对循环非常有用。@Matthew Flaschen:它对这种情况和循环一样有用。@Anthony:所以使用self
的技巧是这里唯一的选择?你能确认Matthew的解决方案不起作用吗?@Michael:首先,这不是一个“把戏”,而是Javascript的工作方式。马修在写这篇评论时的回答是无效的。有一个早期版本的它可能已经工作了,但它涉及将this
作为一个参数传递,这是不必要的,而且是awkard(任何retrieve\u rate
的调用方都会知道这个不必要的特殊要求)。将this
作为参数传递给(函数(self){…})(this)
在setInterval中对我不起作用,因为函数是立即执行的,而不是延迟执行的@Joel Fillmore的解决方案对meThis有效。这对我有效,但似乎不需要调用“call”。默认情况下,retrieve_rate的上下文应设置为self,因为它是作为成员函数调用的。@Dreendle-你说得对,我记得在需要回调函数引用时解决了这个问题。我已经确定了答案,谢谢!这是正确的解决方案。公认的解决方案似乎需要不必要的更多代码,但这种方法有一个缺点。最有可能的是,它将无法与旧版本的IE@Nechehin值得注意。但它仍然是一个更干净的解决方案。它是受支持的,因为IE9对我来说是一个干净的解决方案。如果您需要对IE8的支持,并且正在使用,您可以使用:this.intervalID=setInterval(u.bind(this.retrieve\u rate,this),this.INTERVAL)代码>