[英]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.