Let’s dig a bit on protoype and inheritance in JS!
First we create a “Dog” function.
And we add a “Bark” function to our recently created “Dog” function
Now we are going to create “bailey”, our lovely dog friend.
We’ve only known each other for 8 lines of code, but i already like Bailey, it’s awesome.
Now, let’s make Bailey bark.
Copy and paste the code up there (dog3.js) to a console and then type the following:
You are going to get something like this:
It doesn’t work. :´(
Bailey doesn’t know that the bark function exists.
But we can fix it if instead of adding “Bark” to “Dog”, we add it to Dog’s Prototype.
It works! You can now run “bailey.actuallyBark()” to hear bailey :)
Ok, let’s see what happened here.
There are 2 things we need to know before we continue:
- In JS, everything, is an Object so what we did initially was to add “bark” as a property of “Dog”, so Dog knows about it, but not bailey. (Poor bailey)
— You could run Dog.bark() and see that it works —
2. In JS, functions have a “prototype” property. You can check it by running Dog.prototype in the console.
So what’s the difference between “Bailey” and “Dog”?
Bailey is an instance of and “Dog”, we created it on line 12 when we run:
var bailey = new Dog(‘Bailey’)
Remember when we said Functions had a prototype?
When we run the “var bailey = new Dog()” line, what it does is to map the prototype of Dog as Bailey’s properties.
Or you could also say that bailey inherited its properties from “Dog”.
There is a lot more to prototypes, and JS than what we saw on the previous part of this post. (For example, we haven’t talked about the prototype chain yet, but that’s for another post)
So we know then what a prototype is, and how we can use it to create properties in the instances of a function.
But you could achieve the same results doing something like this:
So what’s the difference then?
While bailey.bark() does indeed work, what we are doing is creating de “bark” function in every dog we create.
Or in more computer-science-words, we are allocating memory space for each barking function, in each instance of “Dog”.
However, when add the “actuallyBark” function into Dog’s prototype, each instance of Dog will be able to bark, but referencing the function in “Dog”.
Or in more computer-science-words, each “actuallyBark” function in each instance of Dog, is referencing the memory space of “actuallyBark” in “Dog”, thus making a better use of the available memory.
The cool part is, if you create many dogs, all their “actuallyBark()” functions will point to the same function, which can save you a lot of memory.
Here’s 2 images comparing the allocation timelines creating 1 Million new Dogs using both the “prototype” (2nd image) and “this” approach (1st image).
I this seems out of context, this post was created in order to complement a question I was asked :)
Also, i’ll translate to Spanish soon :)