Accessing private variables defined with WeakMap inside a derived class - javascript

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

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):
Implementation is simpler
There is no performance degradation
Does not interfere with modularity and putting derived classes in separate files
Infinitely extensible to as many properties, as many classes
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.

Related

JS: Best practice on global "window" object

Following a rapid-prototyping approach, I am developing an application in Marionette.js/backbone.js and heavily used the window-object to bind collections and views to the global stack (e.g. window.app.data, window.app.views).
Of course, it is always better (smoother!) to encapsulate objects in a single class and pass them as parameters where needed. However, this has some limitations when an app and its potential use-cases become really big. And as the data I deal with comes from an API and therefore would be anyway accessible to anybody interested, does that justify storing data in the window-object? Or are there other best-practices in ES6 (or especially Marionette.js) to achieve the same results, but in a more private manner?!
I already go into details about a simple namespacing pattern in JavaScript in another answer. You seem to be already close to this with window.app.data etc.
But it looks like you have a lot of misconceptions about how JavaScript works.
a namespace-based solution that integrates nicely with Browserify/AMD-modules
Then why not use RequireJS? Browserify? or Webpack? There's nothing that a global ridden spaghetti code can do that a modular approach can't do better.
such would be read-only
No. While not impossible to set an object property to read-only, you must explicitly do it with something like Object.seal or Object.freeze.
I do not want to attach objects to the namespace, but actual instances
JavaScript do not have "namespaces" as part of the language, it's just a pattern to scope all your code within literal objects (key-value).
You can put whatever you'd like.
const MyNamespace = {
MyType: Backbone.Model.extend({ /*...*/ }),
instance: new Backbone.Model(),
anyValue: "some important string",
};
Ideally, you would define the namespace within an IIFE to avoid leaking any variable to the global scope.
const app = app || {};
app.MyModel = (function(app){
return Backbone.Model.extend({
// ...
});
})(app);
[...] data I deal with comes from an API and therefore would be anyway accessible to anybody interested
Even if the data is contained within a module that do not leak to the global scope, anybody can access the data. That's how JavaScript works, it's in the user's browser, he can do whatever he wants with the code and the data.
does that justify storing data in the window-object?
No.
Or are there other best-practices in ES6
ES6 has nothing to do with the architecture and patterns you take for your app.
but in a more private manner?!
Like I said earlier, privacy in JavaScript can't be expected.
[encapsulate objects in a single class and pass them as parameters where needed] has some limitations when an app and its potential use-cases become really big.
That's just incorrect. It's the other way around. Software patterns exist solely to help alleviate any limitations that arise as a project grows in scope.
There are multiple patterns you can use that will help deal with the complexity of a bigger app, like:
Modular approach with components
Dependency injection
Service containers
Factories
Events
etc.
I didn't read specifically this book, but JavaScript Design Patterns seems to be a good way to learn more and it demonstrates specific implementations of software patterns in JS.

Is it good practice to encapsulate mutators in a class inside a JS Module?

We're being as functional as possible with our new product using JavaScript. I have an Authentication module that has a tokenPromise which is updated whenever the user logs in or the token is refreshed. Seems we have to allow mutation.
Instead of putting tokenPromise at the module level, I've created a class that only contains high-level functions that limit how the state can be mutated. Other helper functions which are pure (or at least don't need to mutate state) are outside the class. This seems to help a lot in reasoning about when the member might change - it is colocated with all operations that might change it.
I haven't found other examples of such a pattern - is this considered good practice, or is there another way we should be looking at? Here's the class which contains the mutable data, which is exported from Authentication.ts.
export default class Authentication {
public static async getAuthToken(): Promise<string> {
if (!this.tokenPromise || await hasExpired(this.tokenPromise)) {
// Either we've never fetched, or memory was cleared, or expired
this.tokenPromise = getUpdatedTokenPromise();
}
return (await this.tokenPromise).idToken;
}
public static async logOut(): Promise<void> {
this.tokenPromise = null;
await LocalStorage.clearAuthCredentials();
// Just restart to log out for now
RNRestart.Restart();
}
private static tokenPromise: Promise<IAuthToken> | null;
}
// After, at the module level, we define all helper functions that don't need to mutate this module's state - getUpdatedAuthToken(), etc.
A possible principle seems to be: keep objects with mutable state as compact as possible, exposing only high-level compact methods to mutate state (e.g. logOut and refreshAuthToken, not get/set authToken).
I've created a class that only contains high-level functions that limit how the state can be mutated. This seems to help a lot in reasoning about when the member might change - it is colocated with all operations that might change it.
Yes, this is a standard best practice in OOP - the separation of concerns by encapsulation of state changes into the object. No other code outside the object (the class) may mutate it.
Other helper functions which are pure (or at least don't need to mutate state) are outside the class.
I wouldn't go that far. You should put helper functions (methods?) that belong to instances on the class as well, or at least in its direct vicinity - putting them in the same module might be good enough though. Especially when they access "private" parts of the objects. To just distinguish pure from impure functions, you might also use conventions such as get prefixes for pure methods.
An alternative to that is providing a separate immutable interface for your class that contains only the pure methods. You could have this as a second class declaration, and use one method to convert between the representations.
exposing only high-level compact methods to mutate state
I think that's not completely true. You are also implicitly exposing some way to access the state (which the pure helper functions would then use), right? You might as well make those explicit.
When dealing with mutable state, the order of writes and reads does not only matter for the internal view (which parts change when) but also on the external (when does the whole object state change). Some convention, like "properties (and getters) are pure, methods might be impure" will help a lot.

Examples of cases where using private variable/methods in oop languages is useful/necessary [duplicate]

This question already has answers here:
Why "private" methods in the object oriented?
(9 answers)
Why encapsulation is an important feature of OOP languages? [closed]
(5 answers)
Closed 9 years ago.
Whenever I try to research this question the answer usually presented is along the lines of "so the outside world does not have direct access to the local variables." What's missing here for me is the context to which this applies. I get that, for instance, in the code below
function Person(firstName, lastName) {
var _firstName = firstName,
_lastName = lastName;
this.firstName = function(value) {
if (!arguments.length) return _firstName;
_firstName = value;
}};
the variables are considered private because they can only be accessed from calling the functions. What is the significance of this? Why does it matter? And most achingly mysterious is what is a "real life" situation in which the common explanation of "so the outside world does not have direct access to the local variables..." would apply/make sense to someone who has not seen a situation where it matters.
Thanks SO.
It's all to ease development.
Only public properties or methods of objects are accessible to "outside code", i.e. any code that uses an object, accesses its properties or calls its methods can only use the public interfaces of said object. When code uses the public interface in any way, you get code coupling. When you declare a method foo on your object/class, and somewhere in your code you have obj.foo(), that line of code is now coupled to the existence of the foo method. If you want to remove or change the foo method, you (probably) also have to change every line of code that calls it.
Protected and private properties and methods are pieces of code which are explicitly only usable by the class/object itself. "Outside code" cannot couple to it, neither purposefully nor accidentally. When you need to refactor that code, you can be sure the changes are isolated to within the class itself and not worry about possibly breaking tons of other code.
Protected and private properties also don't run the risk of being modified by outside code in an incorrect way. A private property can only be modified by the class/object itself, so the class/object itself is always in full control of the value of that property. This ensures a consistent state of the object.
Therefore, a class/object should keep its public interface to a minimum and keep everything that's not intended or necessary for "public consumption" private. This allows you to focus on your class design in terms of what needs to be public for an object to be useful, and keep the rest of the implementation flexible.
In an OO language, classes should expose behaviour and hide implementation. That's called encapsulation, makes reutilization easier, and is one of the bases of OO.
Generally speaking, variables are part of implementation and not of behaviour. That's why, normally, you don't declare them public.
An example from "real life" is any API you have to interact with (i.e. Amazon REST API). Your work as a developer is easier, if you only have to learn behaviour details (public methods), than if you had to learn the usage of every internal variable of the site. Also, if client code only interacts with the behaviour (again, public methods) of a system, the system may change (i.e. optimize) it's implementation without affecting it's users.

I want to stop using OOP in javascript and use delegation instead

After dabbling with javascript for a while, I became progressively convinced that OOP is not the right way to go, or at least, not extensively. Having two or three levels of inheritance is ok, but working full OOP like one would do in Java seems just not fitting.
The language supports compositing and delegation natively. I want to use just that. However, I am having trouble replicating certain benefits from OOP.
Namely:
How would I check if an object implements a certain behavior? I have thought of the following methods
Check if the object has a particular method. But this would mean standardizing method names and if the project is big, it can quickly become cumbersome, and lead to the java problem (object.hasMethod('emailRegexValidatorSimpleSuperLongNotConflictingMethodName')...It would just move the problem of OOP, not fix it. Furthermore, I could not find info on the performance of looking up if methods exist
Store each composited object in an array and check if the object contains the compositor. Something like: object.hasComposite(compositorClass)...But that's also not really elegant and is once again OOP, just not in the standard way.
Have each object have an "implements" array property, and leave the responsibility to the object to say if it implements a certain behavior, whether it is through composition or natively. Flexible and simple, but requires to remember a number of conventions. It is my preferred method until now, but I am still looking.
How would I initialize an object without repeating all the set-up for composited objects? For example, if I have an "textInput" class that uses a certain number of validators, which have to be initialized with variables, and a class "emailInput" which uses the exact same validators, it is cumbersome to repeat the code. And if the interface of the validators change, the code has to change in every class that uses them. How would I go about setting that easily? The API I am thinking of should be as simple as doing object.compositors('emailValidator','lengthValidator','...')
Is there any performance loss associated with having most of the functions that run in the app go through an apply()? Since I am going to be using delegation extensively, basic objects will most probably have almost no methods. All methods will be provided by the composited objects.
Any good resource? I have read countless posts about OOP vs delegation, and about the benefits of delegation, etc, but I can't find anything that would discuss "javascript delegation done right", in the scope of a large framework.
edit
Further explanations:
I don't have code yet, I have been working on a framework in pure OOP and I am getting stuck and in need of multiple inheritance. Thus, I decided to drop classes totally. So I am now merely at theoretical level and trying to make sense out of this.
"Compositing" might be the wrong word; I am referring to the composite pattern, very useful for tree-like structures. It's true that it is rare to have tree structures on the front end (well, save for the DOM of course), but I am developing for node.js
What I mean by "switching from OOP" is that I am going to part from defining classes, using the "new" operator, and so on; I intend to use anonymous objects and extend them with delegators. Example:
var a = {};
compositor.addDelegates(a,["validator", "accessManager", "databaseObject"]);
So a "class" would be a function with predefined delegators:
function getInputObject(type, validator){
var input = {};
compositor.addDelegates(input,[compositor,renderable("input"+type),"ajaxed"]);
if(validator){input.addDelegate(validator);}
return input;
}
Does that make sense?
1) How would I check if an object implements a certain behavior?
Most people don't bother with testing for method existance like this.
If you want to test for methods in order to branch and do different things if its found or not then you are probably doing something evil (this kind of instanceof is usually a code smell in OO code)
If you are just checking if an object implements an interface for error checking then it is not much better then not testing and letting an exception be thrown if the method is not found. I don't know anyone that routinely does this checking but I am sure someone out there is doing it...
2) How would I initialize an object without repeating all the set-up for composited objects?
If you wrap the inner object construction code in a function or class then I think you can avoid most of the repetition and coupling.
3) Is there any performance loss associated with having most of the functions that run in the app go through an apply()?
In my experience, I prefer to avoid dealing with this unless strictly necessary. this is fiddly, breaks inside callbacks (that I use extensively for iteration and async stuff) and it is very easy to forget to set it correctly. I try to use more traditional approaches to composition. For example:
Having each owned object be completely independent, without needing to look at its siblings or owner. This allows me to just call its methods directly and letting it be its own this.
Giving the owned objects a reference to their owner in the form of a property or as a parameter passed to their methods. This allows the composition units to access the owner without depending on having the this correctly set.
Using mixins, flattening the separate composition units in a single level. This has big name clash issues but allows everyone to see each other and share the same "this". Mixins also decouples the code from changes in the composition structure, since different composition divisions will still flatten to the same mixed object.
4) Any good resources?
I don't know, so tell me if you find one :)

Is there a "typical" usage for private variables?

First, my experience with JavaScript is limited to web development and a little self-study. I want to understand the point of having private members in JavaScript. Take an example,
var myObject = {
WriteWord: function() {
var secret = 'word';
document.writeln(secret);
}
};
myObject.WriteWord();
Private variable secret cannot be seen by the caller. AFAIK, I can notify potential callers of the existence of WriteWord in a few ways:
Document the code. Like jQuery does.
For .NET guys, write a custom visual studio intellisense plugin.
Read the code directly.
Now let's say I minify and even obfuscate the code. Its now unreadable. In my mind, given this scenerio, a lack of documentation is just as good as a private variable.
Is this scenerio uncommon or somehow wrong? What is the importance of private variables in JavaScript?
The whole purpose of encapsulation and private variables, in Javascript or any other language, is to restrict yourself in a way that allows the implementation of a class to be changed at any time without breaking the rest of the code. You can rename secret to any other name or completely remove it and be sure that the code would continue to correctly work.
On the other hand, a public method is a point of coupling between the producer and the consumer and you can't easily change the public interface, method names or arguments without risking to break other parts of the program that depend on it. (This is completely unrelated to wether the code has been obfuscated or how weel docomented it is - if someone is using a public method the coupling will already be there)
Scoping variables carefully in JavaScript eliminates the possibility of another script on your page clobbering a variable.
This becomes a valid concern when working with many different JavaScript libraries/files from possibly many different programmers.
Local ("private") variables are very useful to keep the code readable. Not only because of descriptive names, but also because a developer don't have to keep track of 1000+ variable names.
Also, some variables shouldn't be able to be changed "from the outside". Consider:
function (){
var password = "random word";
window.passwordAsker = function(){
var asked = prompt("Password?", "");
if(asked == password) {
alert("Access granted"); //This should NOT be a real verification method
}
}
}

Categories

Resources