JavaScript Inside Story : More about Prototypes and Inheritance
Tags: javascript, webdev, programming, react
Published: 2021-07-17 23:39:10

I almost picked the title "***JavaScript's Factory for Everything***", but then I changed my mind after reading my older post. Just trying to push my [last post](https://dev.to/mayankav/is-everything-in-javascript-an-object-1alg) here. I don't feel very comfortable writing this, not because I don't understand the stuff but because its something that pretends to be something it really is not. Protesting that prototypal inheritance is not inheritance at all does not change anything. Perhaps if it were not for the comfort of OOPers, it could have been better called ***prototypal wiring*** or maybe ***prototypal delegation***. If you're coming from Java, how would you answer the question, "***Why does Java not suppport multiple class inheritance?***". Well, you'd point out [the Diamond Problem](https://www.cs.cornell.edu/courses/JavaAndDS/abstractInterface/05diamond.pdf), won't you? Given that JavaScript doesn't know this problem how would you explain it not being able to support such a thing? PS: [It can be done but it has its own issues](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#no_multiple_inheritance). Despite its appearance resembling to that of classical inheritance, JavaScript has its own reasons for (not) being able to do certain things. Not asking you to unlearn the classical inheritance take but then to understand JavaScript's way of handling prototypal inheritance you need to drop those intuitive assumptions atleast for the time being. ‍‍

![Just forget it](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ka1pqwg2tobrjion2enk.png)
<hr>
I dont want to recall the time when I started logging objects in the console only to check what's really inside of them. I mean I knew objects had their properties but I also found stuff like \_\_proto\_\_, constructor, prototype, \_\_proto\_\_ again. It would not stop. I kept on digging and it kept on throwing more and then I realized I was willingly stuck in a loop of references. Let me take help of an analogy to explain this to you. Lets assume that any function you create in JavaScript is a House to be put on rent. The House then comes with a bunch of keys ( ***prototype*** ). The bunch of keys has another bunch of small master keys ( ***\_\_proto\_\_*** ) inside it and has a label ( ***constructor*** ) with the name of the house on it. This bunch of keys is given to the tenants ( ***objects created from the function*** ) and the tenants then keep it with them and they like to call it guess what ? ***\_\_proto\_\_***. Heck! confusing. Its not that easy to build analogies here. Just take a look at the diagram I came up with.

![Prototypes in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1b8b48mhm1v6ap0qa21u.gif)<center><h6>[Check out the Ppt](https://www.slideshare.net/Mayankav1/javascript-function-prototype)</h6></center><br>

What you see is what I am going to pen down now. Consider a class ***A*** or simply a function ***A***. The function when created, gets two properties by default namely ***prototype*** and ***\_\_proto\_\_***. ***\_\_proto\_\_*** is a property that is available on everything in JS be it a primitive or an object. Go ahead! try that in your console. It contains some information from the function that was responsible for creating the primitive/object in the first place. Since a function is nothing more than a [Function object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function#:~:text=Every%20JavaScript%20function%20is%20actually%20a%20Function%20object.%20This%20can%20be%20seen%20with%20the%20code%20(function()%7B%7D).constructor%20%3D%3D%3D%20Function%2C%20which%20returns%20true.), the ***\_\_proto\_\_*** property on each and every function takes its value from [Function.prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function#instance_methods). What about the ***prototype*** property? In contrast with ***\_\_proto\_\_*** which is available on anything and everything in JS, ***prototype*** is only available on JavaScript functions. The ***prototype*** property is an object ( only exception being Function.prototype which is a native function ) with two default properties namely ***constructor*** ( refers to the Function/Class itself to which prototype belongs ) and ***\_\_proto\_\_*** . The purpose of ***\_\_proto\_\_*** on ***A.prototype*** is nothing different from that on the function ***A*** itself. ***A.prototype.\_\_proto\_\_*** contains information about the function that was responsible for the creation of ***A.prototype***. Since this object (A.prototype) was automatically created, the function/class responsible for its creation was ***Object***. No wonder why every ***SomeFunction.prototype.\_\_proto\_\_*** gets a default value of ***Object.prototype***. To verify this, try creating an object using the object lietral syntax like so. ‍

```javascript
let randomObj = {};
console.log(randomObj.__proto__ === Object.prototype); // true
```
<center><h6>[Try on Codepen](https://codepen.io/mayankav/pen/VwbpMVY)</h6></center><br>
<hr>
Moving on to instantiating the constructor function, lets do ***let objA = new A();*** to create an object from the function ***A***. ***objA*** gets a ***\_\_proto\_\_*** . We just discussed how everything in JS gets this default property with a value of ***SomeFunction.prototype***, ***SomeFunction*** being the function/class responsible for its creation. No points for guessing its value in this case. Its ***A.prototype***. ‍

```javascript
let objA = new A();
console.log(objA.__proto__ === A.prototype); // true 
console.log(objA.prototype); // undefined
```
<center><h6>.prototype only exists on functions. [Try on Codepen](https://codepen.io/mayankav/pen/VwbpMVY).</h6></center><br>

<hr>
##Prototypal Inheritance‍

All this while what I've been trying to tell you is that ***\_\_proto\_\_*** is just the pen name of ***prototype***. A ***constructor's prototype*** becomes it's ***object's \_\_proto\_\_*** . How does this help? Well since its not the copy but the reference to a function's ***prototype*** which is shared amongst objects created using the function, any new function/property on the ***prototype*** of a function is readily available on the object's ***\_\_proto\_\_*** as well. Though its not a good practice to monkey patch properties on the ***protoype*** of a constructor function. [Read more about that here](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes#:~:text=You%20will%20rarely%20see%20properties%20defined%20on%20the%20prototype%20property%2C%20because%20they%20are%20not%20very%20flexible%20when%20defined%20like%20this.%20For%20example%20you%20could%20add%20a%20property%20like%20so%3A). Interestingly you dont even need to access the patched property via ***\_\_proto\_\_*** . You just access it on the object like ***objA.somePatchedFunction()*** and it gets resolved from ***\_\_proto\_\_*** in the chain. This sounds fun but can very quickly get on the nerves when some object starts patching functions/properties on its ***\_\_proto\_\_*** property causing a ***prototype namespace pollution***. 

Anyway, did you think of this? What happens when you manually alter the ***\_\_proto\_\_*** property on ***objA*** like ***objA.\_\_proto\_\_ = { random : 10 }*** ? Apparently, the link from the function ***A*** breaks and you can no more access the functions patched on ***A.prototype*** and then you get access to properties of the newly set object (***{ random : 10 }***) like ***objA.random***. Apart of assigning a value directly to ***objA.\_\_proto\_\_*** there exist lawful functions ([Object.setPrototypeOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf), [Object.create](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)) in JavaScript to help you do this some of which are [on the verge of being deprecated](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#:~:text=Ill-performing.%20Should%20be%20deprecated.) but that's not my concern for this blog post. This does not even seem very helpful. Why don't we try altering the ***\_\_proto\_\_*** property on ***A.prototype***? Well, that sounds like a plan.

```javascript
function Parent() {
  this.p = 50;
}
Parent.prototype.patchedP = 100;

function Child() {
  Parent.call(this);
  this.c = 200;
}

//  Object.create sets (Child.prototype).__proto__ = Parent.prototype
Child.prototype = Object.create(Parent.prototype);
// Resetting the child constructor may/may not be needed
Child.prototype.constructor = Child;

Child.prototype.patchedC = 400;
console.log(new Child().p); // 50  //undefined if no Parent.call(this)
console.log(new Child().patchedP); //100
```
<center><h6>[Try on Codepen](https://codepen.io/mayankav/pen/qBmRzzj)</h6></center><br>

For the ease of understanding lets try to alter ***Child.prototype***. Let me tell you what am I trying to do. When I create a new object using the Child constructor function, I can say something like ***new Child().c*** and get the expected value i.e. ***200***. What I want is to get a valid value on doing so ***new Child().patchedP*** ie. ***100***. Do you think I should simply make an assignment like so ***Child.prototype = Parent.prototype*** ? Well , no because then when you want to patch some functions on ***Child.prototype***, you will end up patching the orignal ***Parent.prototype***. Changes on Child should not impact Parent or you can't call it inheritance. I better use an ***intermediary object*** to set the ***prototype*** of child. That's why we do this ***Child.prototype = Object.create(Parent.prototype)***. Now when you patch the Child's ***prototype***, it won't impact the Parent (you only patch the intermediary object). 

Did you notice the call to Parent function within the Child function (kind of super if you're coming from Java) ? Try commenting it out in the [pen](https://codepen.io/mayankav/pen/qBmRzzj). That shall leave you with no access to Parent's instance properties i.e. ***p*** here. When you call the Parent with '***this***' (***this*** refers to the newly created object when you say ***new Child()***), the Parent function executes to add the property ***p*** on ***new Child()***. Now in every new instance you create from the Child function, you get access to instance properties of Parent & Child both along with patched properties of both ***Parent.prototype*** & ***Child.prototype***. Additionally, now patching ***Child.prototype*** will not impact Parent. Now that's something we can kind of call inheritance. Just to touch upon the concept of ***prototype chaining***, it goes without saying that if you try to access ***aChild.randomProperty*** given ***aChild = new Child();*** , it shall be first looked up in the property list of ***aChild*** itself, if not found it should be searched for in ***aChild.\_\_proto\_\_*** (the intermediary object we discussed earlier), next in ***aChild.\_\_proto\_\_.\_\_proto\_\_*** until the search reaches ***Object.prototype*** which is the last man standing in the prototype chain.

![A look at new Child()‍](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qmf4qp1wssxc3iu5jjc.PNG)<center><h6>A look at new Child()‍</h6></center><br>

<hr>
##Take Away
1. Every function's ***.prototype*** property is of type - object except function Function. (It's ***.prototype*** property is of type - function)

2. Every function's ***.\_\_proto\_\_*** property is always equal to ***Function.prototype*** and hence of the type - Function.

3. Objects don't have ***.prototype*** property.

4. Every object's ***.\_\_proto\_\_*** property is of type object.

5. An object's ***.\_\_proto\_\_*** property takes its value from the ***.prototype*** property of the Function from which it was created.

6. If an object was not created using any particular function (created using object literal or using Object.create(Object.prototype)), the value of it's ***.\_\_proto\_\_*** property will be ***Object.prototype***.

7. Create an object from a class ***A*** or a function ***A*** : let ***objA = Object.create(A.prototype);*** or ***let objA = new A();***

8. In ES5, inheritance looks like so : ***let anObjectFromParent = Object.create(Parent.prototype);*** ***Child.prototype = anObjectFromParent;***

9. In ES6, the ***extends*** keyword plays the role of ***Object.create(Parent.prototype)*** and the ***super*** keyword invokes the constructor of the parent.‍‍

10. Accessing ***\_\_proto\_\_*** directly on an object is not as optimal as using the ***new*** keyword, ***Object.create*** (to set) and ***Object.getPrototypeOf*** (to get).

11. ***\_\_proto\_\_*** is just a way to programmatically access an object's ***[[Prototype]]*** internal slot which is otherwise not accessible in code.<br><br>

##Originally Posted Here -
https://mayankav.webflow.io/blog/javascript-prototypal-inheritance