2013-04-28 184 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值。

相关问题