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