The Big 5 — Instantiation Patterns in Javascript

Teamer Tibebu
6 min readAug 24, 2020

Before we discuss anything, it’s important to define a couple of key terms that will help us as we journey through this article, namely, ‘instance’ and ‘instantiation’. An instance is something that represents or is an example of something else while instantiation is the production of an instance. Therefore, based off the above definitions, we can confidently gather that an instantiation pattern is a method of producing an instance of something. What exactly are we instantiating? Objects!

As I’m sure you already know, an object is a complex data structure that serves as a way to model real world objects within Javascript. Every real world object has a state and behavior(s), which are represented by a JS object’s properties and methods, respectively. When creating a program, there will come a time when you need to create any number of instances of an object. Instead of manually creating each object one by one, instantiation patterns create efficiency in our code by utilizing a constructor function that defines an objects properties and methods only once, which we later supply values for at the time of instantiation. To clarify, a constructor function’s purpose is to initialize an object.

Now that we have a fundamental understanding of what instantiation patterns are and why we use them, let’s dive deeper and discover the five instantiation patterns you will come across when working with objects in Javascript, enumerated below.

  1. Functional
  2. Functional Shared
  3. Prototypal
  4. Pseudoclassical
  5. ES6 Pseudoclassical

One thing to note here, is that we will be utilizing Pascal, rather than Camel casing, as our naming convention to declare our constructor functions and classes. This should always be done.

Functional

Let’s begin with the functional instantiation pattern. Before you move forward though, take a moment to look through the provided code snippet below and try to get an understanding of what’s going on….

Functional Instantiation Pattern

Above you will see that our constructor function has a few simple steps. An empty object literal is assigned to personObj, it is given its properties (name, age, and favColor) and a single method (greeting), and finally, it is returned. Pretty straightforward, right?

Note that each property on personObj receives its value from our constructor function’s corresponding parameters, so at call time (line 51), you will be supplying arguments that correspond to each. This will also be done for the following instantiation patterns.

Pro

The functional instantiation pattern’s main selling point is its readability and simplicity; all of its methods are contained directly within the object. If you are reading this article, instantiation patterns are going to be relatively new for you, so this pattern would be the most familiar to how you’ve been creating instances of objects and adding properties up to this point.

Cons

One thing you may not have noticed is that with this pattern, every instance of Person will create a new ‘greeting’ function. If this doesn’t seem like a major flaw, imagine your program had to create a hundred instances…a thousand…now imagine your object had many more methods on it! As the number of instances gets larger and larger, you begin to take up unnecessary space in memory to accommodate each function. In comes functional-shared.

Functional-Shared

As you did before, take a moment to look at the code snippet below and point out the differences you see from Functional’s code snippet.

You should have noticed two differences. Firstly, our ‘greeting’ function has moved outside of our constructor function into an object named ‘sharedMethods’. Secondly, is the use of ‘_.extend’ on line 43. Extend is an underscore function that takes in two parameters, the first being the object to which we will copy properties into and the second being the object from which we will grab properties to be copied over. Note that our methods will be copied over by reference, NOT DUPLICATED.

Pro

The con listed for the functional instantiation pattern was that we occupied unnecessary space in memory because with every instance of our object, we continuously created duplicates of our methods as well. The beauty of functional-shared, as mentioned above, is that all of our methods are only created once, but all instances of our objects retain a reference to them.

Con

Ok, we’ve freed up tons of space! What’s the con here?! Unfortunately, there is a drawback of using the extend function. Although our object instances retain reference to the methods housed in ‘sharedMethods’, they will only have reference to the methods that were present at the time of extending. So if we decided to add a method to sharedMethods, all instances that were created prior will not have reference to the added method. Protoypal to the rescue!

Prototypal

You know the routine by now, check out the code snippet below.

Once again, there is only a small change here, notice what our const variable personObj is assigned to. Object.create() is a cool solution to our previous problem that was created by the extend function, where previously created instances do not have reference to newly added methods of our sharedMethods object.

Pulled directly from MDN, "the Object.create() method creates a new object, using an existing object as the prototype of the newly created object”. Simply put, Object.create() builds a bridge between each instance and sharedMethods. When a property/method can not be found in an instance, Javascript walks across that bridge and checks sharedMethods.

Pro

Unlike functional-shared, when sharedMethods is updated, ALL instances have access to the updates.

Con

I don’t necessarily see a flaw here but our next pattern does abstract a few pieces of code for us. Let’s check it out.

Pseudoclassical

You should automatically notice two things about our constructor function; our object’s declaration and return have seemingly disappeared! Oh wow, line 41 looks funky and ‘new’ has appeared in front of the call to our constructor.

Firstly, the disappearance of our object’s declaration/return and the appearance of ‘new’ go hand-in-hand. The new keyword does a few important things…

  1. Initializes an empty object;
  2. Binds ‘this’ to the above object;
  3. Returns the object;

Points 1 and 3 are why we got rid of the object declaration and return in our constructor.

The next thing to take note of is how our methods will be accessed. We will now attach our methods directly on the prototype of our constructor function. This means that, similar to using Object.create(), every instance will have access to all methods that are attached to the prototype without creating any duplicates in memory.

ES6 Pseudoclassical

With ES6 came the class keyword, which serves as a function and helps increase our readability a bit. You’ll notice we still utilize a constructor function and the new keyword to create our object as with Pseudoclassical, but the constructor is housed within the class. But unlike Pseudoclassical, we no longer attach our method to the .prototype property of “Person”, instead, we are placing it directly into our class.

Pro

Classes increase our codes readability!

Con

According to rajaraodv (https://medium.com/@rajaraodv/is-class-in-es6-the-new-bad-part-6c4e6fe1ee65), Class “may make things worse, because ES6’s official “Class” is just a syntactic sugar and not technically and conceptually accurate (i.e. it’s false advertisement or cause for more confusion).”

Conclusion

As we have seen, each pattern has its pros and cons. Get familiar with each one as you’re sure to come across them all in your career as a programmer.

--

--

No responses yet