I have this function in my object:
var time = {
warps : 3,
warpCounter : 50,
warp : function(){
if (this.warps > 0){
this.warps--;
this.warpLoop = 50;
this.warpLoop();
}
},
warpLoop : function(){
setTimeout(function () {
this.increment();
if (warpCounter--){
this.warpLoop();
}else{
if(this.warps > 0){
htmlInteraction.enableButton('warp-button');
}
}
}, 100);
},
};
When I try and call it from another method (using this.warpLoop()
) I get:
Uncaught TypeError: Property 'warpLoop' of object #<Object> is not a function
Why is this?
this context in setTimeout changes, you can use closures to keep the this context.
var test={
warpLoop : function(){
var me=this;//set closure to get the right this context
setTimeout(function () {
console.log("this is:",this); // is window
console.log("me is:",me); // is test
// can call me.warpLoop() but not this.warpLoop()
}, 100);
}
}
test.warpLoop();
your code can look like this:
var time = {
warps : 3,
warpCounter : 3,
warp : function(){
if (this.warps > 0){
this.warps--;
this.warpLoop = 50;
this.warpLoop();
}
},
warpLoop : function(){
//the setTimeout calls me.warpCounter not this.warpCounter
// wich is the same as window.warpCounter since the next
// line is not part of the setTimeout execution you can
// use this
console.log("warpLoop called,warpCounter is",this.warpCounter);
var me=this;
setTimeout(function () {
//me.increment();
if (me.warpCounter--){
me.warpLoop();
}else{
if(me.warps > 0){
//htmlInteraction.enableButton('warp-button');
}
}
}, 100);
},
};
time.warpLoop();
The this
value in JavaScript is not lexically defined. It's defined by the manner in which the function was invoked.
A typical fix is to store the value of this
in a variable in the enclosing scope, then reference it in the inner scope.
var that = this;
setTimeout(function() {
that.whatever()
}, 1000)
While you could also bind the outer this
value to your callback using Function.prototype.bind()
, you seem to have an .increment()
method that isn't throwing the error. So binding may break that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.