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
.
2 Answers
Reset to default 9The 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.