The Prototype Pattern in JavaScript
Tags: javascript, node, webdev
Published: 2019-11-20 01:14:25

Find me on [medium](https://medium.com/@jsmanifest)


There are multiple design patterns that can be implemented in the JavaScript language, and in this post we will be going over the _prototype design pattern_.

The _prototype design pattern_ is an object-based _creational_ design pattern.

If you need a recap on the three types of design patterns that they are generally coincided with, here is a little overview:

1. Creational Design Patterns

Instead of you having to directly instantiate objects directly, these are the ones that create them _for you_. The benefit of this approach is that it gives your program a little more flexibility when deciding which objects need to be created for certain situations.

2. Behavioral Design Patterns

These patterns are focused on the _communication between objects_.

3. Structural Design Patterns

And lastly, these patterns focus on _class and object composition_. They can be used to compose interfaces through inheritance and define ways to compose multiple objects in order to achieve new functionality.

If this is your first time learning about the prototype pattern, you now might have some idea of what to expect. But if you don't then it is my job to help clear that mystery for you, my friend.

So what exactly is the prototype pattern, and what does it do?

![thinking](https://jsmanifest.s3-us-west-1.amazonaws.com/posts/the-prototype-pattern-in-javascript/thinking.jpg)

This pattern's main focus is to help create objects that can be used as blueprints for _any_ object that are created by constructors. It does this through what's called _[prototypal inheritance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)_.

Since JavaScript has native support for prototypal inheritance, it fortunately becomes naturally easy to work with in the language to the point where you don't really need to learn any new concepts but the syntax itself.

With that said, the prototype design pattern is a _very_ useful strategy--which makes it an important and beneficial way to create programs in JavaScript. We will see why in a bit.

When objects are created through the constructor function and contains the `name` property, then further objects created with the same constructor function will also have this same property as shown below:

```js
function Movie(title) {
  this.title = title
}

const harryPotter = new Movie('Harry Potter')
const rushHour2 = new Movie('Rush Hour 2')
const fastAndFurious = new Movie('Fast And Furious')

console.log(harryPotter.constructor.name)
console.log(rushHour2.constructor.name)
console.log(fastAndFurious.constructor.name)
```

It sounds like typical class objects, but in reality it _avoids_ using classes altogether. The prototype design pattern simply creates copies of existing functional objects as opposed to defining brand new objects.

The biggest benefit of using the pattern in JavaScript is the performance boost gained as opposed to object oriented classes. This means that when you define functions inside an object, they will be _created by reference_. In other words, _all child objects will point to the same method_ instead of creating their own individual copies!

Here's a code example of the pattern in action:

```js
const Warrior = function(name) {
  this.name = name
  this.hp = 100
}

Warrior.prototype.bash = function(target) {
  target.hp -= 15
}

Warrior.prototype.omniSlash = function(target) {
  // The target's hp may not be under 50 or this attack will fail on the opponent
  if (target.hp < 50) {
    return
  }
  target.hp -= 50
}

const sam = new Warrior('Sam')
const lenardo = new Warrior('Lenardo')

sam.bash(lenardo)
```

In our code example, we defined a warrior's attack methods by using `Warrior.prototype.<method> = function() {...}`. You can see that we instantiated some warriors with the `new` keyword so now we are looking at two instances. Both instances set their `name` property according to the `name` argument that was passed in by the caller.

When we defined the methods `bash` and `omniSlash` on the prototype as demonstrated, the two separate instances we're looking at are actually referencing the _same_ `bash` and `omniSlash` functions!

```js
const Warrior = function(name) {
  this.name = name
  this.hp = 100
}

Warrior.prototype.bash = function(target) {
  target.hp -= 15
}

Warrior.prototype.omniSlash = function(target) {
  // The target's hp may not be under 50 or this attack will fail on the opponent
  if (target.hp < 50) {
    return
  }
  target.hp -= 50
}

const sam = new Warrior('Sam')
const lenardo = new Warrior('Lenardo')

console.log(sam.bash === lenardo.bash) // true
```

If we instead defined them like this, then they are _not_ the same, so essentially JavaScript has created another _copy of the supposedly same method_ for each instance:

```js
const Warrior = function(name) {
  this.name = name
  this.hp = 100

  this.bash = function(target) {
    target.hp -= 15
  }

  this.omniSlash = function(target) {
    // The target's hp may not be under 50 or this attack will fail on the opponent
    if (target.hp < 50) {
      return
    }
    target.hp -= 50
  }
}

const sam = new Warrior('Sam')
const lenardo = new Warrior('Lenardo')

console.log(sam.bash === lenardo.bash) // false
```

So if we _didn't_ use the prototype pattern like the last example, how crazy would it be when we instantiate many instances? We would have cloned methods cluttering up memory that essentially do the same exact thing, who don't even _need_ to be copied unless it relies on state inside instances!

Another variation of extending prototypes is a syntax like below:

```js
const Warrior = function(name) {
  this.name = name
  this.hp = 100
}

Warrior.prototype = {
  bash(target) {
    target.hp -= 15
  },
  omniSlash(target) {
    // The target's hp may not be under 50 or this attack will fail on the opponent
    if (target.hp < 50) {
      return
    }
    target.hp -= 50
  },
}
```

Which is equivalent to:

```js
const Warrior = function(name) {
  this.name = name
  this.hp = 100
}

Warrior.prototype.bash = function(target) {
  target.hp -= 15
}

Warrior.prototype.omniSlash = function(target) {
  // The target's hp may not be under 50 or this attack will fail on the opponent
  if (target.hp < 50) {
    return
  }
  target.hp -= 50
}
```

## Conclusion

And that concludes the end of this post! I hope you found this to be valuable and look out for more in the future!


Find me on [medium](https://medium.com/@jsmanifest)