2013-04-28 137 views
0

我有一個函數,我在畫布上使用,我試圖清除與.animate函數調用的時間間隔,但是當我打電話給.unbind();時,它仍然記錄未定義,當它記錄超時值時,我不確定爲什麼它不工作,也許你們可以幫助爲什麼'這'不是它在這種情況下應該是什麼?

function Character(model, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { 
    this.model = model; 
    this.srcX = srcX; 
    this.srcY = srcY; 
    this.srcW = srcW; 
    this.srcH = srcH; 
    this.destX = destX; 
    this.destY = destY; 
    this.destW = destW; 
    this.destH = destH; 
    this.timeout = undefined; 

} 

Character.prototype = { 
    draw: function() { 
     return ctx.drawImage(this.model, this.srcX, this.srcY, this.srcW, this.srcH, 
        this.destX, this.destY, this.destW, this.destH); 
    }, 

    animate: function(claymation) { 
     var top = this; <<<<<--------Set the this variable 
     var queue = (function() { 
      var that = this; 
      var active = false; 
      if (!this.active) { 
       (function runQueue(i) { 
        that.active = true; 
        var length = claymation.length -1;  
    >>>>-Set the timeout top.timeout = setTimeout(function() { 
         claymation[i].action(); 
         if (i < length) { 
          runQueue(i + 1); 
          if (i === length - 1) { 
           that.active = false; 
          } 
         } 
        }, claymation[i].time); 
       })(0); 
      } 
     })(); 
     return queue; 
    }, 

    update: function(callback) { 
     callback(); 
    }, 
    unbind: function() { 
     console.log(this.timeout); < Logs undefined 
     clearTimeout(this.timeout); 
     console.log(this.timeout); < Also logs undefined? 
    } 
} 

更新:

我打電話解除綁定上:

player = new Character(playerModel, 0, 130, 100, 100, 150, 150, 100, 100) 
     if (e.which === 39) { 
      player.unbind(); 
      key = undefined; 
     } 

完整的源代碼:https://github.com/Gacnt/FirstGame/blob/master/public/javascripts/superGame.js#L50-L77

+1

你在哪裏/如何調用'.unbind'?您可以通過閱讀關於「this」的工作方式來找到解決方案:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this。 – 2013-04-28 23:22:53

+1

函數的* this *由調用設置,您需要顯示如何調用* unbind *。 – RobG 2013-04-28 23:23:49

+0

@RobG更新.. – Datsik 2013-04-28 23:24:46

回答

3

你的animate功能搞砸了。您已經看到需要將this reference存儲在一個額外變量(that,top,無論什麼)中,因爲它從呼叫到呼叫以及從功能到功能發生變化,但是您未能正確執行此操作。

var top = this; 
var queue = (function() { 
    var that = this; 
    var active = false; 
    if (!this.active) { 
     // use 
     that.active = true; 
     // or 
     top.timeout = …; 
     // or 
     that.active = false; 
    } 
})(); 

雖然top是正確的,並會參考在其上調用該方法的Character例如,that絕對不是 - 它會引用全局上下文(window),這是正常的默認this值(立即)調用函數(表達式)s。因此,this.active也很難有價值,並且您的timeout屬性不會被設置。另外請注意,IIFE並沒有return什麼,所以queueundefined

相反,你似乎想要使用該地方的active變量。然後就做吧!您不必使用類似Java-this的關鍵字來引用「本地」關鍵字 - 該變量只是作用域鏈中的下一個,因此它將被使用。

我不能完全肯定,但它看起來像你想

Character.prototype.animate = function(claymation) { 
    var that = this; // variable pointing to context 
    var active = false; // again, simple local variable declaration 
    if (!active) { 
     (function runQueue(i) { 
      active = true; // use the variable 
      var length = claymation.length -1;  
      that.timeout = setTimeout(function() { // use property of "outer" context 
       claymation[i].action(); 
       if (i < length) { 
        runQueue(i + 1); 
        if (i + 1 === length) { 
         active = false; // variable, again! 
        } 
       } 
      }, claymation[i].time); 
     })(0); 
    } 
}; 
+0

我不是很在意你在這裏,所以我必須使用其中一個? – Datsik 2013-04-29 00:04:30

+0

@XCritics:取決於你需要的,一個實例屬性或一個local-(閉包)-scope變量。我只能說,你用過的'那個'從未做過你想要的。 – Bergi 2013-04-29 01:07:36

0

什麼BERGI的意思是,:

animate: function(claymation) { 
    var top = this; 

在這裏,您機頂盒參考這一點,這是實例(我寧願把它叫做角色,所以你知道它是角色的一個實例)。然後,你必須有它自己的執行上下文和新值這個的IIFE:

var queue = (function() { 
     var that = this; 

這裏設置的IIFE,這是不設置它的默認值的的全局/窗口對象,或者如果處於嚴格模式,將保持未定義狀態。

 var active = false; 
     if (!this.active) { 

所以在這裏你得到window.active,這很可能是不確定的第一次,所以測試結果是真。稍後您可以:

  (function runQueue(i) { 
       that.active = true; 

window.active設置爲true。此外,你正在做的:

  (function runQueue(i) { 
       ... 
      })(0); 

沒有任何需要的IIFE如果你只是傳遞一個固定值,只需使用0無處不在,你有i並刪除IIFE,只需使用函數體,你不應該在範圍鏈上需要額外的對象。

最後,無論是IIFEs的返回什麼,所以隊列仍然是不確定的,所以:

})(); 
    return queue; 

返回udefined值。

相關問題