0

我的对象中有这个功能:

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 

为什么是这样?

4

2 回答 2

5

setTimeout 中的 this 上下文发生变化,您可以使用闭包来保留 this 上下文。

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();
于 2013-05-21T16:08:28.717 回答
3

JavaScript 中的this值不是词法定义的。它由调用函数的方式定义。

一个典型的解决方法是将 的值存储this在封闭范围内的变量中,然后在内部范围内引用它。

var that = this;

setTimeout(function() {
    that.whatever()
}, 1000)

虽然您也可以this使用 将外部值绑定到回调Function.prototype.bind(),但您似乎有一个.increment()不会引发错误的方法。所以绑定可能会破坏这一点。

于 2013-05-21T16:05:50.387 回答