0

I'm using the common WeakMaps pattern to emulate private variables inside es6 classes, but I cannot find a way to have "protected" variables, meaning variables that are private and that can be accessed through derived classes, eg:

var Window = (function() {
    const _private = new WeakMap();
    const internal = (key) => {
        // Initialize if not created
        if (!_private.has(key)) {
            _private.set(key, {});
        }
        // Return private properties object
        return _private.get(key);
    };


    class Window {

        constructor() { 
            // creates a private property
            internal(this).someProperty = "value";
        }
    }

    return Window;
})();

If I create a subclass using the same pattern, how can I access someProperty in the subclass without having to define a getter method in the base class (thus completely defeating the whole purpose of having weakmaps for private properties) ?

If there's no elegant solution by using this pattern, what would be the best course of action to take? I'm building a webapp which can have various "layered windows" displaying various products, loaded from a different script that makes few requests to .php endpoints to gather this information.

The library itself is not intended to be a public library for everyone to get access to, at most other team-mates might have to edit parts of it but they would still respect the defined patterns/conventions

from a security standpoint most requests to other APIs would be done from a separate script handling validation of the payload so what I'm really trying to accomplish is to make reusable Window classes that can use some sort of "protected" variables across derived classes since it would definitely help me in the process of building this particular type of GUI

Row Rebel
  • 267
  • 3
  • 11
  • 2
    Derived classes would have to have access to the `_private` variable so they could get access to the weakMap object. If you want to maintain true privacy, and use this design pattern, then the derived class methods that need access to the private variables would have to be defined inside the scope that has access to `_private` and you'd have to find a way to get the classes themselves known outside the scope (returning multiple classes from the private scope or assigning directly to higher scoped variables). FYI, this is not a problem that really has a good solution in today's Javascript. – jfriend00 Dec 11 '18 at 22:23
  • Many thanks for your input, unfortunately I'll need few different types of windows and hammering everything inside a single file would be unmaintainable.. Do you personally think that it's safe to use the underscore convention for private variables and wait until the specs catches up? This code is not going on a public library for others to use – Row Rebel Dec 11 '18 at 22:49
  • What is "safe" enough for your specific needs depends upon a whole lot of context we do not have. The underscore convention is a documentation convenience and may discourage accidental access. It is not "safe" at all if you're trying to prevent malicious intent. To help you find the best overall solution, we'd have to have the full context of what you're trying to protect, who you're trying to protect it from, how its used and what the consequences are of malicious intent. In other words, you'd have to describe the actual design problem, not just this one attempt at a solution. – jfriend00 Dec 11 '18 at 22:53
  • I'll try to edit the question in a way that defines a bit better the problem and asks for possible solutions in general instead of being exclusive to this design pattern, thanks for your suggestion – Row Rebel Dec 11 '18 at 23:58

1 Answers1

2

The library itself is not intended to be a public library for everyone to get access to, at most other team-mates might have to edit parts of it but they would still respect the defined patterns/conventions

From the description of what you're really trying to do that you added to your question, it sounds like this isn't a "security" issue per se, but rather you're looking for the best programming implementation/convention for your local team that will be using this interface so that it will be clear to other developers which state is "protected" and for use only inside the implementation and not from the outside consumers of the objects.

If that's the case, I'd just go with the underscore convention where a property name on the object that starts with an underscore as in this._someProperty is meant only for internal use in the methods of the object itself (analogous to "protected" members in C++) and not for external use by consumers or users of the object.

Then communicate that in the doc for the implementation and verbally with the team you work with to make sure everyone not only understands that convention in the code you write, but so that they can also consistently use the same convention in their code.

Since it doesn't appear you have an actual security need here, the reasons to go with this type of leading underscore "convention" instead of more involved solutions that provide some real protection of the data from other developers (like what you were attempting to do):

  1. Implementation is simpler
  2. There is no performance degradation
  3. Does not interfere with modularity and putting derived classes in separate files
  4. Infinitely extensible to as many properties, as many classes
  5. Easier to educate the team you're working with on how to do it

A saying once shared with me by a senior developer was that "my code should be as simple as it can be to meet the objectives (correctness, stability, testability, maintainability, extensibility and reuse)". This helped me to strive for simplicity in implementation and avoid over designing beyond what is actually needed.

jfriend00
  • 683,504
  • 96
  • 985
  • 979