[英]JavaScript OO issue when accessing instance methods
我使用过一些有关JavaScript中OOP的教程。 一切顺利,直到我遇到了以下问题...
Result of expression 'this.prepareFrame' [undefined] is not a function.
好。 我正在使用prototype
并使用this
关键字。
在这里查看我的app.js
页面...
// Plain "main" function called by the html page, like <script>main()</script>. This works nicely:
function main() {
engine = new AbstractEngine();
engine.init();
}
// Next creates a new instance of my AbstractEngine class. Seems to work so far:
function AbstractEngine() {}
// The init() method we called is defined afterwards:
AbstractEngine.prototype.init = function() {
this.initLoop();
}
// remark: I'm using "this", and according to the debugger, "this" refers to the AbstractEngine we made an instance of.
// Next, we define the initLoop method:
AbstractEngine.prototype.initLoop = function() {
setInterval(this.tick, 1000 / 30);
}
// Fine, everything works fine so far. Now get to define the "tick" method:
AbstractEngine.prototype.tick = function() {
this.prepareFrame();
this.update();
}
// Ok, we're in trouble. The error message is output to the console and I don't understand why... The prepareFrame() and update() methods are defined right afterwards:
AbstractEngine.prototype.update = function() {
console.log('updating!');
}
AbstractEngine.prototype.prepareFrame = function() {
console.log('preparing frame');
}
// I read my code twice, but didn't find beginner's mistakes like typo or whatever. But well, cosnider I'm a beginner
您需要将initLoop
的定义更改为以下内容:
AbstractEngine.prototype.initLoop = function() {
var that = this;
setInterval(function () {
that.tick();
}, 1000 / 30);
}
这是因为该决议this
被延迟,直到执行时间和执行的时间间隔时, this
指向window
,而不是你的实例AbstractEngine
。
通过将对tick
的调用包装在一个匿名函数中,我们创建了一个闭包,它允许我们捕获that
闭包(将其设置为this
)。 通过在实例 ( 旧的 this)上调用方法 tick
,我们可以恢复“ this”的值。
这个:
setInterval(this.tick, 1000 / 30);
应该:
var that = this;
setInterval(function () { that.tick(); }, 1000 / 30);
或者:
setInterval(this.tick.bind(this), 1000 / 30);
说明:当您简单地传递this.tick
,与执行以下操作相同:
var temp = this.tick;
setInterval(temp, 1000 / 30);
但是现在,当调用temp
时,JavaScript不知道this
指针应该是什么。 该信息会丢失,最终会绑定到全局对象( window
),如果处于严格模式下则将绑定为null
。
因此,您需要以某种方式确保使用适当的this
指针作为一个方法来调用this.tick
。 有两种方法可以做到这一点:
var that = this
的闭包中,您可以正确地调用that.tick
作为原始this
指针上的方法。 bind()
将this.tick
函数this
进行调用,可以确保每次都使用适当的this
调用该方法:换句话说,您甚至可以执行var temp = this.tick.bind(this)
和setInterval(temp, 1000 / 30)
。 请注意, bind
在较旧的浏览器中不可用(特别是IE <= 8以及到目前为止(包括5.1)及以下的所有Safari ),在这种情况下,您将需要es5-shim之类的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.