簡體   English   中英

JS原型類並非所有屬性都可訪問

[英]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,此代碼仍然會失敗。 如果您想將renderLobbyImagesonScheduledItemClick定義為原型方法,則必須編寫

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM