Module Exports best practices for ECMA6 class - javascript

In my nodejs project extensively using the ECMA 6 classes, my question is with regards to exporting this classes.
There are 2 ways for instance:
class MyClass{
constructor(myAttr){this._DB =DB;}
someMethod(){DB.save()}
}
module.exports=Myclass;
Second way:
class MyClass{
constructor(){}
someMethod(obj){var DB =require('DB'); DB.save(obj)}
}
module.exports=new Myclass();
First one relies on the .js to instantiate the class and pass on the variables(DB) While object creation of MyClass, there would however be as many objects created as many requests are coming in of MyClass. However the Class level attributes of MyClass(Db in this case) would not be duplicated.
Second Approach instantiates MyClass but the variable DB is created as many times as the call to SomeMethod is made.
Third approach not so neat is to create global variable for DB and use it :
'use strict'
const DB = require('DB')
class MyClass{
constructor(){}
someMethod(obj){DB.save(obj)}
}
module.exports=new Myclass();
I would like to know what approach is more suitable and in what scenarios.
Best,
-V

Your first approach exports the class and allows anyone who loads your module to create as many instances of your object as they would like.
Your second approach exports only a single object, no matter how many separate callers all load your module. This is called a singleton and all customers of this module would share the same single object.
Your third approach is not much different in practical usage from the second approach. It is also a singleton in that all callers get access to the same object. Your variable DB is not a global. It's a module-level variable that is only accessible to the code inside this module. The third approach has the advantage that the DB variable cannot be messed with by outside code, whereas in your first approach, that data is stored in the object's instance data and can be accessed by anyone.
The first two options offer very different features (freely create many objects vs. singleton). YOU have to decide whether you want to export the class so others can create their own instances or whether you want to export only a single object and all callers share the same object. This is an architectural choice for you to make and we cannot make it for you because it depends only upon what you want to export and what functionality you want the customers of this module to have. There are reasons to want all users of the module to share the same object and there are reasons for each user to be able to instantiate their own object. You have to decide which you want.

Related

Accessing private variables defined with WeakMap inside a derived class

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.

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.

In JavaScript is it better to use modules or Classes?

In ES6 one can export a class in a module or just export functions as per usual. Is one or the other better?
My though is its if one wants a more functional look and feel go with exporting functions where as a more OOP approach would be to export a class.
The point of a Class in ES6 is to be able to create objects (instances) by calling the constructor and for those objects to have properties and methods that operate on those properties.
So, if you're creating a module that intends to expose a way to create new objects that have methods and properties, then by all means expose a constructor or a factory function that can be called to create objects of the desired type.
But, if all you want to share from the module is some functions that can each be used by themselves, then there's really no reason to use the ES6 class because exporting a plain object with several functions as properties is perfectly acceptable for just sharing some functions that can be called independently.
So, the answer is that it depends upon what you're trying to share from the module.
You could, of course, also export a Class with a bunch of static methods, but that offers no particular advantage over just exporting a plain object with functions as properties so there's no particular reason to use an ES6 class for that (other than a syntax preference within the module).

Inherit module in Javascript possible?

I have a module like this :
var myModule= {};
(function( exports ){
init();
exports.doSomething= function(){
return "test";
};
function init(){
initSubscribers();
initListeners();
initForAdmins();//just for the admin
}
//... a lot of functions that maybe doing things depends on if user is admin or normal user
})( myModule );
I have 2 web pages : "Normal page" use "myModule" for normal user and "Admin page" use "myModule" for admin.
Some parts of the module is used by both (normal and admin user) but some parts are specific to the type of user.
I would like to create 2 modules (myNormalModule and myAdminModule) that inherits from a general module (with shared function).
It looks strange to me to "inherit from a module".
My generalModule must be an object or it can be a module ?
You create object types and then inherit from them. You don't inherit from a module. One module can use another module in its own implementation, but that is not inheritance.
So, first create the object structure that you want to use (including inheritance if appropriate) and then, organize that into appropriate modules. And, in organizing your code into modules, a module could define an object type and could then export (e.g. share) that object type and then other modules could either use it or inherit from it. But, the module itself is just a code organizing structure, it isn't an inheritance structure.
So, I'd suggest you figure out your object hierarchy (including inheritance) before you worry about modules and once that is designed, you can then organize it into whatever appropriates modules. For example, if all your object types for this particular problem are pretty much always going to be used together, then they might all be put in one module together.
But, if some object types for this problem might be used by themselves, then it might make sense to break them into their own module for each of sharing only appropriate pieces.
If you have context that you want to share among modules, then there are several different ways to do that depending upon exactly what it is and how it's used. The context could belong to a base object that all other objects inherit from. Or, if the context is more global, it could be stored in one module and then exported to other modules that want access to it.

What's the proper term for this: "javascript object full of functions"?

I've been using this kind of programming pattern lately in order to group logically related functions:
FruitMethods = {
url: "some/path/to/something.durk",
get: function(data) {$.ajax(url, data)},
delete: function(something) { some more function stuff....}
}
You get the picture right? It doesn't seem to really meet the definition of a Class... or does it? A Mixin? Something else? Javascript Object Full Of Functions And Maybe A Variable? JOFOFAMAV?
My vote if for JOFOFAMAV.
PS: Feel free to also chime in with your thoughts on whether or not this is a good practice.
Functionally, it's an object with properties. So, then your question becomes more about what common name would one call it.
Because it has no instance data and doesn't appear like one will be creating new instances of it (e.g. like a class), then it is most like a namespace which is just a named wrapper for a bunch of properties where properties can be any sort of data or functions.
Namespace objects are useful for a bunch of reasons:
Limiting the use of the top level, global namespace thus lowering the chance of a name conflict with other scripts.
An organizational structure/convention for collecting a group of related data or functions.
A hierarchical scheme that makes it easier for categorizing or organizing methods and/or data and referring to them with a simple scheme of category.method like Fruit.get()
I would call that a namespace.
That's a form of singleton - which is basically an object without an external definition: you don't have a 'class' definition and then create instances of that class.
One thing to know about this type of structure is that all of the methods of the object are public ( that may or may not be a problem).

Categories

Resources