[英]JS prototype class not all properties are accessible
我已經定義了一個原型類,其屬性和方法很少,由於某些原因,在某些情況下(主要是涉及回調時),我無法訪問所有屬性。
這是我的代碼(刪除了一些行使其更加清晰)
var Lobby = function (preloader, serverConn) {
// Hold a reference to EventBus
this.serverConn = serverConn;
this.preloader = preloader;
this.session_id = null;
this.scheduleItemService = new ScheduledItemService(this.preloader);
// Instantiate lobby stage
this.stage = new createjs.Stage("lobbyCanvas");
};
Lobby.prototype._renderLobbyImages = function(stage, scheduleItemService) {
// at this point, 'stage' and 'scheduleItemService' are valid!
..
// onScheduledItemClick callback function
this.scheduleItemService.render(stage, this._onScheduledItemClick);
}
Lobby.prototype._onScheduledItemClick = function(event) {
(function(inst) {
inst.serverConn.asyncSend(
'game.lobby',
{ 'action' : 'claim_scheduled_item',
'session_id' : inst.session_id, **//Here, 'inst.session_id' is DEFINED!**
},
function (error, reply) {
**// Here, both 'stage' and 'scheduleItemService' are UNDEFINED! WHY?!?!**
inst.scheduleItemService.startCountdown(inst.stage);
}
});
})(this);
}
ScheduledItemService.prototype.render = function(stage, onScheduledItemClick) {
var scheduled_item = new createjs.Bitmap(preloader.getResult("scheduled_item_img"));
..
..
scheduled_item.addEventListener('click', onScheduledItemClick);
..
}
為什么未在“ stage”和“ scheduleItemService”中定義“ this”中定義this.session_id? 這3個是大堂類的屬性...
我嘗試瀏覽“ this”指針,但實際上找不到“ stage”或“ scheduleItemService”。
我想念什么,對不對?
謝謝 :-)
您的scheduleItemService
變量超出了此處的范圍
function (error, reply) {
scheduleItemService.startCountdown(stage);
}
問題是,即使您沒有使用Promises,此代碼仍然會失敗。 如果您想將renderLobbyImages
和onScheduledItemClick
定義為原型方法,則必須編寫
Lobby.prototype.renderLobbyImages = function(){
// this refers to a Lobby instance
this.scheduleItemService.render(stage, this.onScheduledItemClick);
}
Lobby.prototype.onScheduledItemClick = function(){
// this refers to a lobby instance
}
您還必須在onScheduledItemClick
使用use this
關鍵字。
然后,在您定義的Promise回調中,“ this
”關鍵字不指向實例。 這就是為什么您的代碼出錯。 在此回調內部, this
更改。
為了解決這個問題,在回調之前,將一個臨時變量存儲到“ this
,在這里我將其命名為scope
”。 你可以使用這個scope
,你用同樣的方法this
。
Lobby.prototype.onScheduledItemClick = function(event) {
// this refers to a lobby instance
var scope = this;
this.serverConn.asyncSend(
'game.lobby',
{
'action' : 'claim_scheduled_item',
'session_id' : scope.session_id.bind(scope), // Here scope instead of this. But you could use this as not inside callback. I used scope just for consistency
},
function (error, reply) {
// this does NOT refer to a lobby instance. You must use scope
scope.scheduleItemService.startCountdown(stage);
}
});
編輯1
編輯完代碼后,我仍然可以看到一些錯誤。
我看到在Lobby.prototype._onScheduledItemClick
,您使用的是一個(inst)
變量this.serverConn.asyncSend
,它應該是inst.serverConn.asyncSen
-
編輯2
您的代碼的另一個問題是回調。 范圍未傳遞。 您必須將“回調”與作用域“綁定”。 使用function.bind() ;
所以現在,您的行看起來像:
this.scheduleItemService.render(stage, this._onScheduledItemClick.bind(this));
這樣可以確保在調用回調時,“ this
”變量將具有您在bind
傳遞的參數值。
首先,您不會在this
添加前綴。 與其他一些語言不同, this
在JavaScript中不是可選的。
當你進入一個新的函數調用, this
被重新定義。 您需要保存對其的引用。
this
被定義為被調用函數的父級。 因此,每次調用函數時它都會改變。 人們經常這樣做:
Something.prototype.foo = function() {
var self = this;
doSomething(function() {
// now this has changed, but self still references the original this
});
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.