loading...
Cover image for πŸŽ‰πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§ JavaScript Visualized: Prototypal Inheritance

πŸŽ‰πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§ JavaScript Visualized: Prototypal Inheritance

lydiahallie profile image Lydia Hallie ・5 min read

Ever wondered why we can use built-in methods such as .length, .split(), .join() on our strings, arrays, or objects? We never explicitly specified them, where do they come from? Now don't say "It's JavaScript lol no one knows, it's magic πŸ§šπŸ»β€β™‚οΈ", it's actually because of something called prototypal inheritance. It's pretty awesome, and you use it more often than you realize!

We often have to create many objects of the same type. Say we have a website where people can browse dogs!

For every dog, we need object that represents that dog! πŸ• Instead of writing a new object each time, I'll use a constructor function (I know what you're thinking, I'll cover ES6 classes later on!) from which we can create Dog instances using the new keyword (this post isn't really about explaining constructor functions though, so I won't talk too much about that).

Every dog has a name, a breed, a color, and a function to bark!

When we created the Dog constructor function, it wasn't the only object we created. Automatically, we also created another object, called the prototype! By default, this object contains a constructor property, which is simply a reference to the original constructor function, Dog in this case.

The prototype property on the Dog constructor function is non-enumerable, meaning that it doesn't show up when we try to access the objects properties. But it's still there!

Okay so.. Why do we have this property object? First, let's create some dogs that we want to show. To keep it simple, I'll call them dog1 and dog2. dog1 is Daisy, a cute black Labrador! dog2 is Jack, the fearless white Jack Russell 😎

Let's log dog1 to the console, and expand its properties!

We see the properties we added, like name, breed, color, and bark.. but woah what is that __proto__ property! It's non-enumerable, meaning that it usually doesn't show up when we try to get the properties on the object. Let's expand it! πŸ˜ƒ

Woah it looks exactly like the Dog.prototype object! Well guess what, __proto__ is a reference to the Dog.prototype object. This is what prototypal inheritance is all about: each instance of the constructor has access to the prototype of the constructor! 🀯

So why is this cool? Sometimes we have properties that all instances share. For example the bark function in this case: it's the exact same for every instance, why create a new function each time we create a new dog, consuming memory each time? Instead, we can add it to the Dog.prototype object! πŸ₯³

Whenever we try to access a property on the instance, the engine first searches locally to see if the property is defined on the object itself. However, if it can't find the property we're trying to access, the engine walks down the prototype chain through the __proto__ property!

Now this is just one step, but it can contain several steps! If you followed along, you may have noticed that I didn't include one property when I expanded the __proto__ object showing Dog.prototype. Dog.prototype itself is an object, meaning that it's actually an instance of the Object constructor! That means that Dog.prototype also contains a __proto__ property, which is a reference to Object.prototype!

Finally, we have an answer to where all the built-in methods come from: they're on the prototype chain! πŸ˜ƒ

For example the .toString() method. Is it defined locally on the dog1 object? Hmm no.. Is it defined on the object dog1.__proto__ has a reference to, namely Dog.prototype? Also no! Is it defined on the object Dog.prototype.__proto__ has a reference to, namely Object.prototype? Yes! πŸ™ŒπŸΌ

Now, we've just been using constructor functions (function Dog() { ... }), which is still valid JavaScript. However, ES6 actually introduced an easier syntax for constructor functions and working with prototypes: classes!

Classes are only syntactical sugar for constructor functions. Everything still works the same way!

We write classes with the class keyword. A class has a constructor function, which is basically the constructor function we wrote in the ES5 syntax! The properties that we want to add to the prototype, are defined on the classes body itself.

Another great thing about classes, is that we can easily extend other classes.

Say that we want to show several dogs of the same breed, namely Chihuahuas! A chihuahua is (somehow... 😐) still a dog. To keep this example simple, I'll only pass the name property to the Dog class for now instead of name, breed and color. But these chihuahuas can also do something special, they have a small bark. Instead of saying Woof!, a chihuahua can also say Small woof! πŸ•

In an extended class, we can access the parent class' constructor using the super keyword. The arguments the parent class' constructor expects, we have to pass to super: name in this case.

myPet has access to both the Chihuahua.prototype and Dog.prototype (and automatically Object.prototype, since Dog.prototype is an object).

Since Chihuahua.prototype has the smallBark function, and Dog.prototype has the bark function, we can access both smallBark and bark on myPet!

Now as you can imagine, the prototype chain doesn't go on forever. Eventually there's an object which prototype is equal to null: the Object.prototype object in this case! If we try to access a property that's nowhere to be found locally or on the prototype chain, undefined gets returned.


Although I explained everything with constructor functions and classes here, another way to add prototypes to objects is with the Object.create method. With this method, we create a new object, and can specify exactly what the prototype of that object should be! πŸ’ͺ🏼

We do this, by passing an existing object as argument to the Object.create method. That object is the prototype of the object we create!

Let's log the me object we just created.

We didn't add any properties to the me object, it simply only contains the non-enumerable __proto__ property! The __proto__ property holds a reference to the object we defined as the prototype: the person object, which has a name and an age property. Since the person object is an object, the value of the __proto__ property on the person object is Object.prototype (but to make it a bit easier to read, I didn't expand that property in the gif!)


Hopefully, you now understand why prototypal inheritance is such an important feature in the wonderful world of JavaScript! If you have questions, feel free to reach out to me! 😊

✨ Twitter πŸ‘©πŸ½β€πŸ’» Instagram πŸ’» GitHub πŸ’‘ LinkedIn πŸ“· YouTube πŸ’Œ Email

Discussion

pic
Editor guide
Collapse
mukeshsharma1201 profile image
Mukesh Kumar

You should really make a tutorial for creating these beautiful Gifs as well :)

Collapse
lydiahallie profile image
Lydia Hallie Author

Lmao β€œhi guys welcome to my tutorial today we start off by having caffeine-induced insomnia and getting random ideas for animated gifs using Keynote at 4AM...”. But I may actually totally do it if it can help people :)

Collapse
combizs profile image
combizs

I just auth'd to the community so I can β™₯️ the parent comment and compliment how awesome the GIF is. easy to read, clean transition and carries the point across.

Collapse
iamsahithyan profile image
Sahithyan

yes. please do it. The GIFs are awesome. "Tell us how" in a video.

Collapse
techdebtor profile image
sam

Please do it!

Collapse
ivopauly profile image
Ivo Pauly

Please do it!

Collapse
mrmagician profile image
Avnish

Please do it

Collapse
savokiss profile image
savokiss

Please do it!

Collapse
kp profile image
KP

please do it!

Collapse
amartya149 profile image
Amartya Aishwarya

Would love to see that tutorial

Collapse
mjmhtjain profile image
mjmhtjain

i second that

Collapse
pflash profile image
Precious adeyinka

Yes please, lydia I was just gonna ask it will mean alot to me, thank you mukesh for asking this question ur great mate!πŸ˜‰

Collapse
sebbdk profile image
Sebastian Vargr

Prototype, no one really uses it directly but it is one of the main architectural points of the language...

Instead we now have class, because, then we can look more like C# and Java, yay for pointless uniformity!

I wonder how pop JS would have looked today if we didn’t have all the baggage from poorly researched classical languages. :)

Collapse
jankapunkt profile image
Jan KΓΌster

I already mentioned in another discussion that still I wonder why prototypical inheritance is rarely taught at CS or SE classes. It's a very strong paradigm and mostly misused due to misunderstanding.

Collapse
sebbdk profile image
Sebastian Vargr

Having used JS’s version 10-12’ish years ago days I can definitely understand why.

I had a lot of problems making it have good verbosity, I might give it a go again sometime, back then I was kind of a rookie. :)

That being said, I think it comes down to familiarity, most languages are made to resemble classical OOP and their structures, the commonly accepted truth has been that is was the most optimal way.

But if we look back, most of those features were based on popularity and not research on what would be better to manage state, have high verbosity etc.

Just look at Java literally founded on hype, but I digress, I am seeing a strong pull towards more diverse paradigms, it will be interesting to see were that takes us. :)

Collapse
mickmister profile image
Michael Kochell

It reminds me of how interpreters evaluate variables through different closures/scopes. If it's not in this scope, let's check the next one, and so on. Once we've checked everything up to global scope and still haven't found the variable, it is considered undefined. Very useful information.

Collapse
Sloan, the sloth mascot
Comment deleted
Collapse
sebbdk profile image
Sebastian Vargr

Not really, but I can see how you could interpret it like that.

I’m not sure how to help you understand how proper debate is done in this context.

But an accusation without argumentation is a really bad way to start a conversation. :/

Honestly it pissed me off a bit.
But maybe we can turn this around?

Thread Thread
Sloan, the sloth mascot
Comment deleted
lydiahallie profile image
Lydia Hallie Author

Okay let’s stop this discussion here or continue on hackernews lol

Thread Thread
sebbdk profile image
Sebastian Vargr

Actually yes, you could have asked for sources, and I could have given them.

Instead you decided to attack my intentions, which you have no way of knowing.

Please think about this before you comment more. I’ve given up my initial annoyance/insulted feelings, that was not easy, you clearly have not.

I’m not trying to keep some kind of moral high ground here, but I don’t know were to meet you if you keep this level of unwillingness to have a constructive debate.

Thread Thread
pablorn profile image
Pablo Reyes

In the end you married or no?

Thread Thread
dexygen profile image
George Jempty

Why did you necro this?

Collapse
vncz profile image
Vincenzo Chianese

It'd probably be a better language.

Collapse
artoodeeto profile image
aRtoo

the GOAT! suggestion for the next topic is this. hehe. thank you for this. :)

Collapse
lydiahallie profile image
Collapse
ptejada profile image
Collapse
emmabostian profile image
Emma Bostian ✨

You have a true gift for blogging. Keep on writing!

Collapse
adriaanbd profile image
Adriaan

Excellent articles, excellent visuals. Here's a resource I used to drill this down, with excellent explanations and visuals as well: objectplayground.com/

Collapse
focus97 profile image
Michael Lee

Came here with a "yeah, I understand JS prototypes but a visualization could be cool" and then realized how much this exceeded expectations. Great job with not just the explanations but also the animated graphics. Nicely done indeed.

Collapse
umashankar profile image
umashankar

It was Yesterday, when i was working on project. Inspecting Front-end code with google chrome dev tools and this thought struck my mind who would've written all these codes,where they came from.

thepracticaldev.s3.amazonaws.com/i...

And this day i found this article explaining everything very beautifully.
Thank you!

Collapse
pencillr profile image
Richard Lenkovits

This is awesome. It made me realize again that there are a lot of things I 'just use' without understanding it. Which is bad. :D

Collapse
ptejada profile image
Pablo Tejada

Good read. All this time I thought of JS prototype as a cool way to add functionality to objects that have already been instantiated. It all makes sense now :)

Seeing how an object is composed from a class was cool too.

Collapse
bigleegeek1 profile image
bigleegeek1

Your visual JS posts are the best for newbies as they provide the pertinent info needed!

bigleegeek

Collapse
efti profile image
Nighty Greek

The main reason that i subscribed to this site it was just to write you here a huge Congratulations and Thanks for making so simple the whole concept of Prototyps in JS. Really you gave me a huge boost to keep reading and practising the OOP part of JS that it can be useful for React.
Your series of visualized concepts of JS is a amazing work and a quite productive way to teach very easy complicated -at least for us the beginners- concepts!
Again thank you!

Collapse
nanouchkaya profile image
Claudine

Thank you so much for this awesome tutorial! Well explained. I finally understand what all those _proto_ mean in my console πŸ˜‚

Love your gif, they're very practical for understanding.

Collapse
mrjaypeasmith_36 profile image
Jay

Superb! I'm learning React at the moment and this helped me understand some of the structure of Class based components!

Collapse
lydiahallie profile image
Lydia Hallie Author

That's great! Yeah it's definitely an important thing if you want to understand what's really going on when you're using React.

Collapse
ericwu91 profile image
EricWu91

Awesome content! I've been constructing objects in Javascript for a while, and never thought about adding methods directly to the prototype to save memory.

Thanks for that! πŸŽ‰

Collapse
develawyer profile image
Zamir Narro πŸ‡΅πŸ‡ͺ

You made it easy to follow and understand. Thanks Lydia! πŸ€—

Collapse
hinasoftwareengineer profile image
Hina-softwareEngineer

Nice effortπŸ‘πŸ‘πŸ‘

Collapse
veebuv profile image
Vaibhav Namburi

Hey @lydia! Just discovered this and your twitter!

Amazing work pushing such excellent content soon after coming out of a bootcamp! Looking forward to all your future content!

subscribed

Collapse
zafer profile image
Zafer

Excellent! Must have been hard to prepare

Collapse
vvilliam5 profile image
Williams Oluwafemi

Lydia, I really admire how articulate and visual your posts are, great article as usual. Keep up the awesome work :)

Collapse
lydiahallie profile image
Collapse
tobiasramzy profile image
Collapse
iggy_code profile image
Ignatius Sani

Informative article

Collapse
gamzerol profile image
Gamze Erol

it was an issue I was working on these days. Thank you, Lydia. With this animations, i completely figure out 🀩

Collapse
tothricsaj profile image
Richard Toth

Yhea, I am fond of your articles. Could you write one about book recommendation?

Collapse
mukherjee96 profile image
Aritra Mukherjee

The animated diagrams help a lot! Thanks. ☺

Collapse
ben profile image
Ben Halpern

Wow, these are great!

Collapse
rboesp profile image
Robert Boespflug

This is amazing thank you!!

Collapse
francasix profile image
FrancaSix

Β« Daisy is cute, Jack is fearless Β» but nice article anyway.

Collapse
armw4 profile image
Antwan R. Wimberly

Very, very, very... koolllllllllll yes!!! Thank you (great art πŸ–Ό and animations) πŸ’ͺ🏽 πŸ™πŸΏ πŸ‡ΊπŸ‡Έ

Collapse
prabutdr profile image
Prabhakaran

Very good explanation with images, loves it.

Collapse
tanth1993 profile image
tanth1993

thank you for your sharing. now I know why we don't need to code: arr.prototype.filter(...), but arr.filter(..).