我的对象中有这个功能:
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);
},
};
当我尝试从另一种方法(使用this.warpLoop()
)调用它时,我得到:
Uncaught TypeError: Property 'warpLoop' of object #<Object> is not a function
为什么会这样?
答案 0 :(得分:5)
setTimeout中的这个上下文发生了变化,你可以使用闭包来保持这个上下文。
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();
您的代码可能如下所示:
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();
答案 1 :(得分:3)
JavaScript中的this
值不是词法定义的。它由调用函数的方式定义。
一个典型的解决方法是将this
的值存储在封闭范围内的变量中,然后在内部范围中引用它。
var that = this;
setTimeout(function() {
that.whatever()
}, 1000)
虽然您也可以使用this
将外部Function.prototype.bind()
值绑定到回调,但您似乎有一个.increment()
方法不会抛出错误。所以绑定可能会破坏它。