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.
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.
Top comments (0)