What is a prototype in JavaScript?
Tags: javascript
Published: 2021-11-29 07:11:46

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;
}
```
The syntax to create a new object with a constructor looks like this:
```
const me = new Person("Nicole", 19);
```
`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;
}
```
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");
```
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
}
```
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");
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6x708u88xq5me7up53uu.png)

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;
```
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}`);
   }
}
```
Single prototype property:
```
Person.prototype.introduce = function(){
   console.log(`Hello, my name is ${this.name}`);
}
```
##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;
}
```
Then you create an object with this constructor.
```
const me = new Person("Nicole", 19);
```
The constructor of `me` is `Person`. I think that much is clear.
```
me.constructor === Person
→ true
```
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
```
**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
```
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.