2

Here's the code snapshot:

class UIController {
    constructor() {
        let eleNodes = new EleNodes()
        this.idsAndClasses = eleNodes.idsAndClasses
        this.nodes = eleNodes.nodes
    }
    async OpenCloseForm() {
        let formContainer = this.nodes.solcomForm
        //...other code
    }
}

When I, later-on, assign OpenCloseForm as a function on click, this does no longer reference che class this.nodes but the context of this becomes of the pressed button. Here the on click setup:

//this in this case references to the object setup in yet another class
//where I also call this event handler
this.uiCtrl.solcomForm.on("click", this.uiCtrl.OpenCloseForm)

Is there a way to reference back to the actual data within the class?

ps: I looked up already that question marked and it does lack the context which is in this case the use of class instead of functions, so I can't derive a solution from another context.

Eugene
  • 217
  • 8
  • 24
  • 1
    Whether `OpenCloseForm` is a class method or a standalone `function` (or a function on a prototype) does not matter. The problem and the possible solutions are all the same. If you showed us the part where you are attaching the function as the onclick handler, we could be more specific. – Bergi Jun 10 '19 at 09:19
  • @Bergi Added this part ;) – Eugene Jun 10 '19 at 09:26
  • 2
    Since you're loosing the context, you need to either do `/*...*/.on("click", () => this.uiCtrl.OpenCloseForm())` or `/*...*/.on("click", this.uiCtrl.OpenCloseForm.bind(this.uiCtrl))` to have the correct context at execution – VLAZ Jun 10 '19 at 09:30
  • @VLAZ This indeed worked, feel free to answer this way and I'll up-vote it as solution. Still, it's so damn stupid for a class loose it's own context like this... – Eugene Jun 10 '19 at 09:51
  • 1
    @Eugene the class doesn't "loose" its context, the *call* is loosing it. In JS, `this` works via a delayed context initialisation, so it's decided at the time you invoke the function. By only giving the handle to a function as a callback, at the time it's going to be executed (the event fires), you don't have the context of which object to execute it *against*. The dupe goes into more detail about all this. – VLAZ Jun 10 '19 at 09:53
  • @VLAZ Mmmm, had to think on what you said, and it makes sense. Knowing that class is just syntax sugar for what is function "objectification" it still bugs me why the _calling_ isn't capable to retain the context automatically... so the new `class` syntax is not that much effective(probably, tell me if I'm mumbling) in terms of functionality because it doesn't add an intuitive approach like in other OOP languages. – Eugene Jun 10 '19 at 10:07
  • 1
    @Eugene it serves in terms of representing classes in a more OO way. But I do agree that it's unintuitive that you can't pass a *method* and expect it to be called against the same object. It does make some sense when you consider that a `class` is still using prototype inheritance, so a class with method `doStuff` will actually create add `doStuff` to the prototype of the object and each instance will be using the *same* method by just relying on the lazy context initialisation to change `this`. The alternative is to use up a lot of memory and keep one method per object instance. – VLAZ Jun 10 '19 at 11:43
  • 1
    So, all in all, it makes sense when you know what's happening under the hood but it does appear like it's doing something different if you're not absolutely familiar with how JS does stuff. If coming from a different OO language, you could very justifiably think the actual operation is different. However, other languages, like Java, do try to hide stuff from you and it *might* appear that they are doing similar things but this is actually smoke and mirrors (a bit like JS's class) - you are passing the equivalent of `() => this.doStuff()` which preserves context in JS and *works* in Java. – VLAZ Jun 10 '19 at 11:49

0 Answers0