简体   繁体   English

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

[英]JS prototype class with private methods not accessing properties

I'm new to JS and especially to prototypes. 我是JS的新手,尤其是原型。 I have this class and I cannot figure out how to access the properties. 我有这个课,我不知道如何访问属性。

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();
};

Calling code: 调用代码:

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

What am I doing wrong accessing 'renderLobbyImages' ?? 访问“ renderLobbyImages”时我做错了什么?

Thank you :-) 谢谢 :-)

In javascript, this is not resolved based on where it is declared/used. 在JavaScript中, this不是基于在声明/使用解决。 It is resolved when it gets called. 调用时已解决。 (see: How does the "this" keyword in Javascript act within an object literal? ). (请参阅: Javascript中的“ this”关键字如何在对象文字中起作用? )。

Therefore, in the code above, since this is called in the callback to sendMessage() , and since sendMessage is asynchronous (meaning the callback will be called long after the call to start() have returned), this is therefore referring to the global object (which is window in web browsers, something unnamed in node.js). 因此,在上面的代码中,由于this是在sendMessage()的回调中调用的,并且由于sendMessage是异步的(这意味着回调将在对start()的调用返回后很长时间被调用),因此, this是指全局对象(在Web浏览器中是window ,在node.js中未命名)。

So effectively, your code is doing this (no pun intended): 如此有效,您的代码正在执行此操作(无双关语):

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

Since there are no global variables called stage or scheduleItemService both are effectively undefined! 由于没有称为stagescheduleItemService全局变量,因此实际上都是未定义的!

Fortunately, there is a workaround for this. 幸运的是,有一种解决方法。 You can capture the correct object in a closure: 您可以在闭包中捕获正确的对象:

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

Alternatively, you can pass the correct object ( this ) into an IIFE: 或者,您可以将正确的对象( this )传递给IIFE:

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

or: 要么:

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

Or in this case, since stage and scheduleItemService are not functions, you can even pass them directly: 或者在这种情况下,由于stagescheduleItemService不是函数,因此您甚至可以直接传递它们:

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

There are lots of solutions to this problem. 有很多解决此问题的方法。 Just use the one you're most comfortable with. 只需使用最舒适的一种即可。

Two problems. 两个问题。

  1. this is missing in your constructor function on scheduleItemService . thisscheduleItemService的构造函数中丢失。

  2. Some functions you call to assign values seem to be not returning anything. 您调用的某些分配值的函数似乎未返回任何内容。

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

Your calling method is alright. 您的调用方法还可以。

this always refers to the calling object. this总是指调用对象。 When you say... 当你说...

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

... your calling object is lobby which has all the fields the start() function needs. ...您的调用对象是lobby ,该lobby具有start()函数所需的所有字段。 But there initialization seems to be not working properly. 但是初始化似乎无法正常工作。

Please read this MDN starter guide . 请阅读此MDN入门指南

Also we are having a some discussion about classical and prototype based OOP in this question. 这个问题上,我们还将讨论基于经典和基于原型的OOP。 Please see the answer of Paul S for more about the tutorial I mentioned. 有关我提到的教程的更多信息,请参见Paul S答案 Please see my answer if you need to see the tutorial in classical OOP light. 如果您需要以经典的OOP格式观看教程,请参阅我的答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM