How do I change scope of “this” in setInterval and setTimeout functions

余生长醉 提交于 2019-12-24 05:40:19

问题


How is it possible to use this inside of setInterval and setTimeout calls?

I want to use it like :

function myObj() {
  this.func = function(args) {
    setTimeout(function() { 
      this.func(args);
    }, 1000);
  }
}

Some time ago I did it for .onclick event this way :

this.click = function(func) {
  this.elem.onclick = (function(func, obj) {return function(){func.apply(obj)} })(func,this);
};

but I don't know how I can do it for intervals and timeouts.


回答1:


The easiest way is to just save this into a local. The local self isn't changed by the context in which setInterval and setTimeout callbacks are invoked. It will instead maintain the original this value

function myObj() {
  var self = this;
  this.func = function(args) {
    setTimeout(function() { 
      self.func(args);
    }, 1000);
  }
}



回答2:


In theory, you could do continue using this everywhere and avoid that, self etc like this:

setTimeout.call(this, function() { 
  this.func(args);
}, 1000);

...or...

setTimeout.apply(this, [function() { 
  this.func(args);
}, 1000]);

...but, doing so causes the following error in Firefox 22+:

NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object


If you're using jQuery 1.4+, you can avoid this by using jQuery.proxy() instead of call or apply:

setTimeout( $.proxy(function() {
  this.func(args);
}, this), 50);

There is some more detail, and alternatives using native ECMAScript 5, Underscore.js and prototype.js at this other answer.



来源:https://stackoverflow.com/questions/11366643/how-do-i-change-scope-of-this-in-setinterval-and-settimeout-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!