Before we go, I should warn you that I’m going to focus on describing the class instantiation patterns rather than thoroughly explaining the implementation of the data structures. Just keep in mind that we are going to explore building stacks and queues with objects rather than arrays. More specifically, we will use a property called
storage that is an object, not an array. Now I know what you’re pondering.
That is a beautiful question. Please ask it all the time (but please don’t troll me by leaving “Why?” in the comments section of this blog post). In this case, the answer to “Why?” may be a tad disatisfying. The answer is “because we can”, but don’t worry! It’ll be fun. Now, let’s start instantiating some motherhugging classes.
1. Functional Instantiation
Car class, instances might have a
price property). It can also have properties that store functions. These functions serve as methods that are tightly associated with the instance.
- Creates new copies of the same functions when creating a new instance of the same class. This lack of reuse takes up more memory and can leave an unsavory taste in some programmers’ mouths.
- There is no quick way to modify all instances of the class after they’ve been created. This will become more clear after examining the other instantiation tactics.
- Private variables can be created/used by harnessing closure scope superpowers, but I won’t get into that today.
- Could be used to create callable instances (i.e., the class could return a function rather than an object filled with properties).
2. Functional Instantiation w/Shared Methods
By utilizing an object filled with methods, several classes can be created that have the same methods without creating new copies of said methods. The classes will use their own function references to refer to the same set of shared methods. Therefore, using shared methods eats up less memory than functional instantiation without shared methods.
- Reuses functions (which conserves memory) by getting function references from a utility such as Underscore.js’s
- Retains the same benefits as functional instantiation without shared methods.
3. Prototypal Instantiation
The key to prototypal instantiation is the use of
Object.create() to utilize shared methods. Unlike functional instantiation with shared methods, there is no need to use an
While it’s possible to use a prototype’s functions with
Object.create(ExampleClass.prototype);, it’s also possible to (ironically) avoid the word “prototype” altogether by using
- Reuses shared functions via
- Unlike functional instantiation, function references are shared. Each instance of the class does not get its own function references that point to the shared methods. This saves even more memory (although it is a very small improvement).
- Unlike functional instantiation, there is no way to use closure scope to enforce privacy of variables.
- Variables are stored on the returned object (aka
instance), which means the shared stack methods need to use the keyword
thisto access the necessary data. It’s not a huge bummer, but if you’re a beginner, then
thiscan be a confusing concept.
- Can use prototype chains for dynamic method modification and inheritance (subclasses!).
4. Pseudoclassical Instantiation
This is the most commonly used class pattern. It’s also the most complicated because, in addition to using the
this keyword, it involves two concepts that the other class patterns don’t require: the
new keyword and prototypes. Prototypal instantiation uses prototypes via
Object.create(), but pseudoclassical instantiation needs you to explicitly type out
ClassName.prototype.methodName, which is just another source of confusion for beginners.
Also, it’s the only class pattern that uses a true constructor for creating new instances. Other class patterns use instantiator functions that explicitly return a new instance. The pseudoclassical class pattern does not perform such a return thanks to the
- Uses prototype chains to provide methods to instances of a class.
- Allows for dynamic method modification and inheritance (subclasses!) via prototype chains.
- Refers to the instance that’s being created with the
- Needs the
newkeyword to make an instance of a class.
- Has a true constructor that is named with a noun rather than a verb. The name is capitalized.
- Is the most commonly used class pattern.