Javascript JS原型类并非所有属性都可访问

Javascript JS原型类并非所有属性都可访问,javascript,prototype,Javascript,Prototype,我已经定义了一个原型类,它只有很少的属性和方法,由于某些原因,在某些情况下(主要是在涉及回调时)我无法访问所有属性 这是我的代码(删除了一些行以使其更清晰) 为什么在“this”中定义this.session_id,而没有定义“stage”和“scheduleItemService”??这3个是Lobble类的属性 我试图在“this”指针中浏览,但实际上找不到“stage”或“scheduleItemService” 我错过了什么,对吗 谢谢:-)首先,您没有在物品前面加上this。与其他一些

我已经定义了一个原型类,它只有很少的属性和方法,由于某些原因,在某些情况下(主要是在涉及回调时)我无法访问所有属性

这是我的代码(删除了一些行以使其更清晰)

为什么在“this”中定义this.session_id,而没有定义“stage”和“scheduleItemService”??这3个是Lobble类的属性

我试图在“this”指针中浏览,但实际上找不到“stage”或“scheduleItemService”

我错过了什么,对吗


谢谢:-)

首先,您没有在物品前面加上
this
。与其他一些语言不同,
在JavaScript中不是可选的

当您输入新的函数调用时,
将重新定义此
。您需要保存对它的引用

被定义为被调用函数的父函数。因此,每次调用函数时,它都会更改。以下是人们经常做的事情:

Something.prototype.foo = function() {
    var self = this;
    doSomething(function() {
        // now this has changed, but self still references the original this
   });
};

您的
scheduleItemService
变量超出了此处的范围

function (error, reply) {
      scheduleItemService.startCountdown(stage);
}
问题是,即使你没有使用承诺,这段代码仍然会失败。如果要将
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
中使用
this
关键字

然后,在您定义的promise回调中,“
this
”关键字不会指向该实例。这就是为什么您的代码会出错。在这个回调中,
this
会发生变化

为了解决这个问题,在回调之前,将一个临时变量存储到“
this
,这里我将它命名为
scope
”。您可以使用此
范围
与使用
的方式相同

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

在您的代码编辑之后,我仍然可以看到一些错误

我在您的
大厅.prototype.\u onScheduledItemClick
,您使用的是
(inst)
变量,
this.serverConn.asyncSend
,它应该是
inst.serverConn.asyncSen

--

编辑2

代码的另一个问题是回调。未传递范围。您必须使用范围“绑定”回调。这是使用

现在,您的线路看起来像:

this.scheduleItemService.render(stage, this._onScheduledItemClick.bind(this));

这样,当调用回调时,“
This
”变量将具有传入
bind

的参数值,这里的原型在哪里?为什么没有
This
?我认为您需要使用“this.stage”和“this.scheduleimservice”,因为“this.session\u id”可以工作。如果是这样,那么为什么
this.session\u id
可以在第一个函数中工作?我认为这是因为该方法是通过apply/call/bind调用的。(我认为OP只是忘记在第二个函数中键入
this.
)秘密在于scheduleItemService.render方法:)问题是这两个方法中的this都可以引用任何内容。如果OP想要使用它,那么方法应该在原型或构造函数上。否则,必须始终使用bind/call/apply调用它们,否则会影响全局。“或者这是一个错误。”丹达维斯说,这里还有第二个问题<代码>此在JavaScript中不是可选的。
this.scheduleItemService.render(stage, this._onScheduledItemClick.bind(this));