具有私有方法的JS原型类不访问属性

JS prototype class with private methods not accessing properties

本文关键字:访问 属性 原型 JS 有方法      更新时间:2023-09-26

我是JS的新手,尤其是原型。我有这个类,我不知道如何访问属性。

var Lobby = function (preloader, serverConn) {
  // Hold a reference to EventBus
  this.serverConn = serverConn;
  this.preloader = preloader;
  this.scheduleItemService = new ScheduledItemService(this.preloader);
  this.stage = new createjs.Stage("lobbyCanvas");
};
Lobby.prototype.start = function(me, signedRequest) {
    sendMessage(data, function() {
       // inside this scope this.stage is undefined!
       renderLobbyImages(this.stage, this.scheduleItemService);
    });
};
function renderLobbyImages(stage, scheduleItemService) {
  stage.update();
};

呼叫代码:

var lobby = new Lobby(preloader, serverConn);
lobby.start(me, status.authResponse.signedRequest);

访问"renderLobbyImages"时我做错了什么??

谢谢:-)

在javascript中,this不会根据声明/使用位置进行解析。它在被调用时得到解决。(请参阅:Javascript中的"this"关键字如何在对象文字中起作用?)。

因此,在上面的代码中,由于this在对sendMessage()的回调中被调用,并且sendMessage是异步的(意味着回调将在对start()的调用返回很久之后被调用),因此this指的是全局对象(在web浏览器中是window,在node.js中未命名)

因此,有效地,您的代码正在这样做(并非双关语):

sendMessage(data, function() {
   renderLobbyImages(stage, scheduleItemService);
});

由于没有称为stagescheduleItemService的全局变量,所以这两个变量实际上都是未定义的!

幸运的是,有一个解决办法。您可以在闭包中捕获正确的对象:

var foo = this;
sendMessage(data, function() {
   renderLobbyImages(foo.stage, foo.scheduleItemService);
});

或者,您可以将正确的对象(this)传递到IIFE:

(function(x){
    sendMessage(data, function() {
        renderLobbyImages(x.stage, x.scheduleItemService);
    });
})(this); // <-------- this is how we pass this

或:

sendMessage(data, (function(a){
    return function(){
        renderLobbyImages(a.stage, a.scheduleItemService);
    }
})(this));

或者在这种情况下,由于stagescheduleItemService不是函数,您甚至可以直接传递它们:

sendMessage(data, (function(a,b){
    return function(){
        renderLobbyImages(a,b);
    }
})(this.stage, this.scheduleItemService));

这个问题有很多解决办法。只要用你最舒服的。

两个问题。

  1. scheduleItemService上的构造函数中缺少this

  2. 您为赋值而调用的某些函数似乎没有返回任何内容。

     new createjs.Stage("lobbyCanvas");
     new ScheduledItemService
    

您的调用方法可以。

this总是指调用对象。当你说。。。

varlobby = new Lobby();
lobby.start();

您的调用对象是lobby,它具有start()函数所需的所有字段。但那里的初始化似乎没有正常工作。

请阅读本MDN入门指南。

在这个问题上,我们还讨论了经典OOP和基于原型的OOP。有关我提到的教程的更多信息,请参阅Paul S的回答。如果你需要从经典OOP的角度看教程,请看我的答案。