In JavaScript is it better to use modules or Classes? - javascript

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).

Related

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.

Module Exports best practices for ECMA6 class

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.

overloading vs overriding in javascript

In a recent JavaScript interview I was asked about overloading vs overriding. I know this is a concept in Java. But is there something similar in JavaScript, and if so what would be code examples? My understanding is that overloading isn't common in javascript. Why would you need to use "overloading" in JS?
OverRiding is a bit clearer to me - an example of over riding would be in subclassing where you are inheriting from a super class but over riding some methods/properties to create unique ones for a sub class.
JavaScript does not support overloading.
JavaScript supports overriding, so if you define two functions with the same name, the last one defined will override the previously defined version and every time a call will be made to the function, the last defined one will get executed.
more read here http://blog.mastykarz.nl/overloading-functions-javascript/
There's a nice example of 'faking' JavaScript function overloading here: https://stackoverflow.com/a/457589/2754135
You basically use a parameter in your function that takes an object, that object contains any number of parameters you want.
It's not actually overloading obviously, cause that's not possible in JavaScript.
there is no need for the traditional concept of overload in javascript, because of its dynamic nature. In the more traditional programming languages, as Java, you can define a method multiple times with different signatures and the language will correctly use the method you want to call just using the signature: thats called overload of methods. On the other hand override is the possibility to redefine a method of the parent class in the child class.
To do overload in javascript it is common practice to use last parameter that is called options. For example
function yourFunction(firstParam, secondParam, options) {};
the options is just a javascript object that have props you want to pass. Then you can use the so called "options" pattern to check for props.
To do override it is more difficult in pure javascript because of the prototypal nature of the language: when you "extend" a base object with a new one, you can use .call() function of the constructor object passing this to decorate the newly created object with the parent props.
While JavaScript does not support overloading in a traditional sense,
More than the required arguments may be passed at any time to a JavaScript method, and accessed through the arguments variable. This is functionally similar.

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.

Javascript: Module Pattern vs Constructor/Prototype pattern?

I would like to know if the module pattern or Constructor/protoType pattern is more applicable to my work.
Basically I am using unobtrusive javascript -- the HTML document has a reference to the .js file.
My understanding of the module pattern:
call an INIT method (which is basically a public method i can create and return using the module pattern)
In the INIT method, assign all click events etc.
This sounds like the perfect pattern for my situation, as I don't need to create Objects and inheritance hierarchies etc.
My understanding of the Constructor/Prototype pattern:
for creating objects
for using inheritance (i.e. Subtypes of a supertype)
Am I correct, that for providing unobtrusive javascript, the module pattern is ideal?
Constructor-functions and prototypes are one of the reasonable ways to implement classes and instances. They don't quite correspond to that model so you typically need to choose a particular scheme or helper method to implement classes in terms of prototypes. (Some background on classes in JS.)
The module pattern is typically used for namespacing, where you'll have a single instance acting as a store to group related functions and objects. This is a different use case from what prototyping is good for. They're not really competing with each other; you can quite happily use both together (eg put a constructor-function inside a module and say new MyNamespace.MyModule.MyClass(arguments)).
Module pattern is by far easier and more elegant than prototype. However, thinking mobile first. It is not a relevant pattern for medium/large objects because the initialization needs to parse the whole block before starting. The multiple closures also create circular dependencies that the garbage collector does not free (especially IE), it results in a heavier memory footprint not freed until the window (or tab) is closed - check chrome task manager to compare-
The loading time is inversely proportional to the object size using module pattern while this is not the case for prototypal inheritance.
Statements above are verified through multiple benchmarks like this one: http://jsperf.com/prototypal-performance/54
As seen in last test. Small objects are better off being initialized as plain object ( without these patterns). It is suitable for single objects not requiring closure nor inheritance. It is wise to assess if you even need these patterns.
Prototype pattern helps us to extend the functionality and there is only one instance of functions in a memory irrespective of the number of objects. In Module patter, each object creates a new instance of functions in memory but it provides with concept of private/public variables and helps in encapsulating the variables and functions.

Categories

Resources