Classes and Instantiation Patterns in javaScript
July 5, 2015
Any construct that is capable of producing a fleet of similar instances conforming to some interface can be called a Class.
Without entering into the debate about the OOp aspects of the javaScript language specific to Classes, and if classes/instances truely exists in js, let’s just rely on the above definition, and explore the different patterns available to us for defining Classes and instantiating them.
In general
Every pattern need to take care of the basics:
- Create a new object
- Assign some properties and methods to it
- Return the new decorated object
The Functional pattern
It does just what is suppose to do:
Pros & Cons
The functional pattern have the advantage of returning methods that were defined within the constructor’s lexical scope, therefore creating closures (and making the object constrution pretty clear). The very same principle that give the functional pattern the closure advantage also define its drawback. As the methods are declared within the the lexical scope of the constructor, instantiating a class via the functional pattern will result in duplicating all its methods, meaning new functions stored in new spots in memory.
The Functional-shared pattern
Born as an effort to limit the drawbacks of the functional pattern, it moves the methods declaration outside the lexical scope of the class, extending it methods by reference. In this way each istance will have pointers to the same functions without duplicating them:
…definitely a WET solution.
WET: Write Everything Twice or We Enjoy Typing
With the help of a little helper we could refactor the functional-shared pattern to be a little more DRY instead
DRY: Don’t Reapeat Yourself
Pros & Cons
The functional-shared pattern solve the cons we saw in the functional pattern. But, it still have a big drawback: the pointers in each instance are created during the instantiation only, meaning that if we add or edit shared methods those won’t be available to our instances unless we update them (i.e. by invoking the extend helper again on each of our instances.).
The Prototypal pattern
By now you probably noticing a trend in how this blog post is structured, we are building up a better pattern to solve the drawbacks of the previous one. And this is where the Prototypal pattern come handy. By relying on the prototypal delegation on which javaScript objects obey, it provide a handy way to keep in sync any istance with its class. Long story short: the prototypal pattern allow us to edit, add and remove methods on the Class and automagically have each istance updated accordingly.
Pros & Cons
There are’n much drawbacks with this Pattern, as it solve all our issues we encountered sofar. So, maybe there is not a better way, but just a sweeter way…
Pseudoclassical
Sometime an advantage could be given by the language itself and its syntactic sugar, and guess what, mr. Pseudoclassical pattern is very very sweet:
Final thoughts and performance
The clear question we should all ask our self is: which pattern should we use? As for everything the answer is: it depends. It depends on the codebase you are working on and which pattern is most used there, in that case will be a good idea to stick to that. For example the Pseudoclassical is the preferred pattern in MVC’s such as backbone. Another interesting aspect to take into consideration when deciding which pattern to use could be related to performance, but this is a subject for a another blog post…
Thanks to:
Hack Reactor for being awesome.
Charles Crame for helping in proof reading this post.
Ryan Atkinson for his inspirational blog.