[英]JS prototype class not all properties are accessible
I have defined a prototype class with few properties and methods and for some reason I cannot access all the properties in some cases (mainly when callbacks are involved). 我已经定义了一个原型类,其属性和方法很少,由于某些原因,在某些情况下(主要是涉及回调时),我无法访问所有属性。
Here is my code (removed some lines to make it clearer) 这是我的代码(删除了一些行使其更加清晰)
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);
..
}
Why this.session_id is defined in 'this' while 'stage' and 'scheduleItemService' are not defined?? 为什么未在“ stage”和“ scheduleItemService”中定义“ this”中定义this.session_id? these 3 are properties of Lobby class...
这3个是大堂类的属性...
I tried browsing in 'this' pointer and I really couldn't find 'stage' nor 'scheduleItemService'. 我尝试浏览“ this”指针,但实际上找不到“ stage”或“ scheduleItemService”。
I'm missing something, right? 我想念什么,对不对?
Thank you :-) 谢谢 :-)
Your scheduleItemService
variable is out of scope here 您的
scheduleItemService
变量超出了此处的范围
function (error, reply) {
scheduleItemService.startCountdown(stage);
}
The thing is even if you did not use Promises, this code would still fail. 问题是,即使您没有使用Promises,此代码仍然会失败。 If you want to define the
renderLobbyImages
and onScheduledItemClick
as prototype methods, you'd have to write 如果您想将
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
}
You must also use the use this
keyword in the onScheduledItemClick
. 您还必须在
onScheduledItemClick
使用use this
关键字。
Then, inside the promise callback you defined, the " this
" keyword does not point back to the instance. 然后,在您定义的Promise回调中,“
this
”关键字不指向实例。 That's why you are getting errors with your code. 这就是为什么您的代码出错。 Inside this callback, the
this
changes. 在此回调内部,
this
更改。
To fix this, before the callback, store a temporary variable to the " this
, here I named it scope
". 为了解决这个问题,在回调之前,将一个临时变量存储到“
this
,在这里我将其命名为scope
”。 You can use this scope
the same way you use this
. 你可以使用这个
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);
}
});
Edit 1 编辑1
After your code edit, I can still see some errors. 编辑完代码后,我仍然可以看到一些错误。
I see that in your Lobby.prototype._onScheduledItemClick
, you are using a (inst)
variable, this.serverConn.asyncSend
, it should be inst.serverConn.asyncSen
我看到在
Lobby.prototype._onScheduledItemClick
,您使用的是一个(inst)
变量this.serverConn.asyncSend
,它应该是inst.serverConn.asyncSen
-- -
Edit 2 编辑2
Another problem with your code is the callback. 您的代码的另一个问题是回调。 The scope is not passed along.
范围未传递。 You have to "bind" your callback with a scope.
您必须将“回调”与作用域“绑定”。 This is used using function.bind() ;
使用function.bind() ;
So now, your line looks like : 所以现在,您的行看起来像:
this.scheduleItemService.render(stage, this._onScheduledItemClick.bind(this));
This will make it so that when your callback is called, the " this
" variable will have the value of the argument you pass in bind
. 这样可以确保在调用回调时,“
this
”变量将具有您在bind
传递的参数值。
Firstly, you aren't prefixing your things with this
. 首先,您不会在
this
添加前缀。 Unlike some other languages, this
is not optional in JavaScript. 与其他一些语言不同,
this
在JavaScript中不是可选的。
When you enter a new function call, this
is redefined. 当你进入一个新的函数调用,
this
被重新定义。 You'll want to save a reference to it. 您需要保存对其的引用。
this
is defined as the parent of the called function. this
被定义为被调用函数的父级。 Therefore it changes each time a function is called. 因此,每次调用函数时它都会改变。 Here's what people often do:
人们经常这样做:
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.