最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I change scope of "this" in setInterval and setTimeout functions - Stack Overflow

programmeradmin0浏览0评论

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.

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.

Share Improve this question asked Jul 6, 2012 at 17:05 JohnJohn 7,91017 gold badges67 silver badges96 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 9

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);
  }
}

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.

发布评论

评论列表(0)

  1. 暂无评论