DEV Community

Nicole Schmidlin
Nicole Schmidlin

Posted on

What is a prototype in JavaScript?

When I started working on a project with Vue.js, I came to the realization that I do not know much about JavaScript. Since then I’ve been looking into JS which then lead me to Object Oriented Programming in JavaScript. I learned about many things, but the concept I struggled the most with was probably prototypes.

With this blog post I hope I can explain it in an understandable way.

Small introduction

A constructor is a function that creates new objects. In JavaScript it looks like this:

function Person(name, age) {
   this.name = name;
   this.age = age;
}
Enter fullscreen mode Exit fullscreen mode

The syntax to create a new object with a constructor looks like this:

const me = new Person("Nicole", 19);
Enter fullscreen mode Exit fullscreen mode

me now has the name “Nicole”, and age 19. Easy and simple as you would expect.

Now imagine we wanted to create an object Person with the properties arms, hands, fingers, and name:

function Person(arms, hands, fingers, name) {
   this.arms = arms;
   this.hands = hands;
   this.fingers = fingers;
   this.name = name;
}
Enter fullscreen mode Exit fullscreen mode

When you create four instances of Person, it will look like this:

const person1 = new Person(2, 2, 10, "Alice");
const person2 = new Person(2, 2, 10, "Bob");
const person3 = new Person(2, 2, 10, "Ursula");
const person4 = new Person(2, 2, 10, "Hanspeter");
Enter fullscreen mode Exit fullscreen mode

Pretty annoying and very repetitive… That’s when prototypes become useful.

Prototypes

Prototypes are used to share properties among all instances of an object. Take the example from above:

Person.prototype = {
   constructor: Person,
   arms: 2,
   hands: 2,
   fingers: 10
}
Enter fullscreen mode Exit fullscreen mode

With this prototype object, creating four instances of Person with the constructor looks much cleaner and is also less work:

function Person(name) {
   this.name = name;
}
const person1 = new Person("Alice");
const person2 = new Person("Bob");
const person3 = new Person("Ursula");
const person4 = new Person("Hanspeter");
Enter fullscreen mode Exit fullscreen mode

As I said, much smaller and less repetitive work, but they all have the same properties as the ones created above without a prototype.

with vs without prototype

Not only does it look cleaner, but it is easier to change the values.

Let’s say you — for some really stupid reason — typed in 2 hands for each person, but the program actually only creates people with one hand (why we would need the properties arms and fingers is beside the point now). You would have to go through every. single. instance of the object and change not only the value 2 hands, but also 10 fingers. With only four instances, you would need to make eight changes. With the prototype, you will only ever need to make two changes.

It’s not the best example, but I think it gets the point across.

Single prototype property vs prototype object

Above I used a prototype object which is good when many properties should be shared. However, if there is only one shared property, you can write it like this:

Person.prototype.age = 30;
Enter fullscreen mode Exit fullscreen mode

No need to make it bigger than it has to be.

Prototype functions

It is also possible to store functions as properties with a prototype.
Prototype object:

Person.prototype = {
   introduce: function() {
      console.log(`Hello, my name is ${this.name}`);
   }
}
Enter fullscreen mode Exit fullscreen mode

Single prototype property:

Person.prototype.introduce = function(){
   console.log(`Hello, my name is ${this.name}`);
}
Enter fullscreen mode Exit fullscreen mode

constructor: person

You might have noticed that I defined the constructor in the prototype object. This is important to do, because if we do not define the constructor, the objects will have Object as its constructor and not Person.

Alright, now let’s take this sentence apart to make it clearer.

You have a constructor for an object.

function Person(name, age){
   this.name = name;
   this.age = age;
}
Enter fullscreen mode Exit fullscreen mode

Then you create an object with this constructor.

const me = new Person("Nicole", 19);
Enter fullscreen mode Exit fullscreen mode

The constructor of me is Person. I think that much is clear.

me.constructor === Person
→ true
Enter fullscreen mode Exit fullscreen mode

However, when you create a prototype object for Person and do not define the constructor, me will have the constructor Object.

Person.prototype = {
   introduce: function() {
      console.log(`Hello, my name is ${this.name}`);
   }
}
const me = new Person("Nicole", 19);
console.log(me.constructor === Person);
console.log(me.constructor === Object);
→ false
  true
Enter fullscreen mode Exit fullscreen mode

But why?

The Prototype chain

To explain the prototype chain, let’s focus only on objects first. When you create an object, you can check its properties with hasOwnProperty.

But where does this come from? We never defined it anywhere, yet we can use it. The answer is that all objects inherit from Object which has its own prototype properties. You can check it by creating a simple object and check its constructor.

let exampleObject = {
   something: "hi"
}
console.log(exampleObject.constructor === Object);
→ true
Enter fullscreen mode Exit fullscreen mode

So all objects stem from Object, can use its prototype properties and have Object as a constructor. This makes sense.

Now, when you create a prototype object, it is an object and thus inherits from Object. That is why you have to define the constructor or otherwise your instances of Person will have the constructor Object.

Object.prototype -inherited by-> Person.prototype ={} -inherited by-> me

Thank you

To be honest, I did not expect this article to get that long (I don’t know what happened), so if you made it till here, seriously, thank you for reading.

Top comments (0)