setTimeout 后未找到对象方法
Posted
技术标签:
【中文标题】setTimeout 后未找到对象方法【英文标题】:Object Method not Found after setTimeout 【发布时间】:2013-03-14 01:41:56 【问题描述】:LoCEngine.prototype.runGame = function()
// Initiate our game loop
ctx.clearRect(0, 0, 800, 600);
this.drawScene(this.curScene);
if(this.gameRunning)
window.setTimeout(Engine.runGame, 1000 / this.framerate);
LoCEngine 是我一直在构建的一个实验性引擎,用于了解 html5 Canvas 游戏的来龙去脉。到目前为止一直很开心,直到我进入游戏循环。 runGame 会随着时间的推移而被调用,这会清除 Canvas 并调用 drawScene 函数。
LoCEngine 实例存储在变量 Engine 中(不确定在 setTimeout 中使用它是否是最佳实践...请告知)
它会在第一帧正确调用 this.drawScene,但在超时 (30 FPS) 时会抛出异常:
TypeError: this.drawScene is not a function
不太清楚为什么...我敢肯定这只是我没有遇到过的关于 JS 的问题。提前谢谢你。
【问题讨论】:
this
指的是我相信的窗口对象。你应该使用LocEngine.framerate
【参考方案1】:
您需要这样做才能正确调用方法:
LoCEngine.prototype.runGame = function()
// Initiate our game loop
ctx.clearRect(0, 0, 800, 600);
this.drawScene(this.curScene);
if(this.gameRunning)
window.setTimeout(function()
Engine.runGame()
, 1000 / this.framerate);
当您将Engine.runGame
传递给setTimeout()
时,它只是传递了方法引用本身,而其中的对象部分丢失了。因此,当它被setTimeout()
的内部调用时,它在this
中不再具有正确的对象引用,并且当代码尝试基于this
调用另一个方法时,它会生成您看到的错误。解决方法是使用我展示的匿名函数自己调用它。
也可以使用.bind()
,它在内部为您做同样的事情。但是,旧版浏览器不支持.bind()
,所以我倾向于只使用匿名函数。
【讨论】:
谢谢,这似乎已经解决了这个问题。以上是关于setTimeout 后未找到对象方法的主要内容,如果未能解决你的问题,请参考以下文章