JavaScript Instantiation Patterns and Their Key Differences
Tags: beginners, javascript
Published: 2020-06-28 21:13:18

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.

```javascript
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](https://dev-to-uploads.s3.amazonaws.com/i/apr0od9cwxp07aj3ur0u.png)

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:

```javascript
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:

```javascript
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. 

```javascript
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".

```javascript
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)