DEV Community

Austin Brown
Austin Brown

Posted on

JavaScript Instantiation Patterns and Their Key Differences

Instantiation patterns, in short, are methods (not necessarily a JavaScript method) by which we can create multiple instances of objects that share the same initial properties/methods. Assuming that you already have a basic understanding of this concept and why you would want to do it, let's get right into it.

The five main types are:

  • Functional
  • Functional Shared
  • Prototypal
  • Pseudoclassical
  • Pseudoclassical ES6

Each one in the list is generally considered to be better than the last, but I mainly would like to go over their differences abstractly and show some examples.

Functional

Perhaps the most simplistic of the bunch would be the first in this list; Functional. Let's look at a basic example of how this would be set up.

const Person = function(nameLast, nameFirst, age) {
  const obj = {};
  obj.fullname = `${nameFirst} ${nameLast}`;
  obj.age = age;
  obj.isMillenial = function() {
    return age >= 24 && age <= 39;
  }
  obj.rename = function(nameLast, nameFirst) {
    obj.fullname = `${nameFirst} ${nameLast}`;
  }
  return obj;
};

const austin = Person("Brown", "Austin", 26);

Below is what the object "austin" would look like as created on the last line.

Alt Text

As you can see, the idea is to eliminate the need to manually type out the property names or add the methods each time you want to create a new object—in this case, a person object.

This one probably has the least advantages, other than that it is simple to understand/write and achieves the intended goal of saving time and lines of code.

Functional is fine for small sets of data, however, it is generally considered the least efficient because for every new object the code is copied in memory and thus is not as efficient as it could be as you'll see in later examples.

Functional Shared

Functional Shared's main differences from traditional Functional are that the methods that all instances share take up less space in memory since they can all point to the same location in memory for each function instead of copying them each time.

Here is an example of Functional Shared that will create the same instances as the last example:

const Person = function(nameLast, nameFirst, age) {
  const obj = {};
  obj.fullname = `${nameFirst} ${nameLast}`;
  obj.age = age;
  Object.assign(obj, methods);
  return obj;
};

const methods = {
  isMillenial: function() {
    return this.age >= 24 && this.age <= 39;
  },
  rename: function(nameLast, nameFirst) {
    this.fullname = `${nameFirst} ${nameLast}`;
  }
}

const austin = Person("Brown", "Austin", 26);

The main drawback with Functional Shared, as opposed to some of the more advanced instantiation patterns, is that if you decide to alter the shared methods ("const methods" in the example) at any point after creating an instance ("const austin" on the last line), those changes will not be reflected in any of the instances created before this point, and all of the new instances will point to a new set of methods.

Prototypal

The most important change in Prototypal is the introduction of "Object.create()". "Object.create()" is a JavaScript method which fixes the aforementioned problem in Functional Shared.

As expected, here is another example:

const Person = function(nameLast, nameFirst, age) {
  const obj = Object.create(methods);
  obj.fullname = `${nameFirst} ${nameLast}`;
  obj.age = age;
  return obj;
};

const methods = {
  isMillenial: function() {
    return this.age >= 24 && this.age <= 39;
  },
  rename: function(nameLast, nameFirst) {
    this.fullname = `${nameFirst} ${nameLast}`;
  }
}

const austin = Person("Brown", "Austin", 26);

On the second line, "Object.create()" basically combines the purpose of the second and fifth from the previous example and adds additional functionality. "Object.create()" will permanently extend the methods passed as an argument onto the instances created with it. Now, if say we decide to add a new method to "const methods", all instances, no matter when they were created relative to when this change is made, will show the new method.

Pseudoclassical

In Pseudoclassical, we introduce ".prototype" and "new" and change the use of "this" keyword.

const Person = function(nameLast, nameFirst, age) {
  this.fullname = `${nameFirst} ${nameLast}`;
  this.age = age;
};

Person.prototype.isMillenial = function() {
    return this.age >= 24 && this.age <= 39;
};
Person.prototype.rename = function(nameLast, nameFirst) {
  this.fullname = `${nameFirst} ${nameLast}`;
};

const austin = new Person("Brown", "Austin", 26);

Instead of extending our methods onto each object, we add methods directly to the 'class' of "Person" using ".prototype" and a constructor function creates the objects. On the last line, 'new' sets the context for the 'this' keyword seen in the code above to refer to whichever specific instance you create (such as 'const austin' on the last line).

Pseudoclassical ES6

The main difference here is just that the syntax is brought up to ES6, so it looks a little cleaner and has new keywords "class" and "constructor".

class Person {
  constructor(nameLast, nameFirst, age) {
    this.fullname = `${nameFirst} ${nameLast}`;
    this.age = age;
  };
  isMillenial() {
      return this.age >= 24 && this.age <= 39;
  };
  rename(nameLast, nameFirst) {
    this.fullname = `${nameFirst} ${nameLast}`;
  };
};

const austin = new Person("Brown", "Austin", 26);

Summary

*(each issue fixed continues on to the patterns that follow)

Functional

  • Simple/Readable
  • Inefficient

Functional Shared

  • Introduces "this" keyword
  • More efficient than Functional
  • Shared methods will not change after instantiation

Prototypal

  • Introduces "Object.create()"
  • Fixes shared methods issue from Functional Shared

Pseudoclassical

  • Introduces ".prototype" and "new" instead of "Object.create()"
  • Constructor function - eliminates need for declaring object literal
  • Takes less code to write than Prototypal

Pseudoclassical ES6

  • ES6 syntax (cleaner, less code, introduces "class" and "constructor" keywords)

Top comments (0)