Prototype Inheritance ⛓
Questions 🤔
- What is Prototypal inheritance
- What is the difference between Prototype and [[Prototype]] and
__proto__
- What happens when you try to use or mutate an object using
__proto__
in your production code? - What happens when you call a constructor function with the
new
keyword- A new empty object is created
- The context object
this
is bound to the new empty object - The new object is linked to the function’s prototype property
- If we see the empty object prototype it will return its own constructor unless another value is added explicitly to the function
- After an object is created, for example using the
new
keyword, how can we access the prototype object that the instantiated object is linked to?
There is two way to access a prototype in javascript- Object.getPrototypeOf(yourObject)
- yourObject.proto
- What is the difference between the classical and the prototypical inheritance?
You might of think prototypal inheritance
in javascript is similar to inheritance from any other object-oriented programming language.
But, the answer is partial YES. Prototypal inheritance
is somewhat similar to other programming languages.
And the base definition of inheritance remains the same i.e extending base class properties into child class as simple as that.
JavaScript had a prototypal inheritance from the beginning. It was one of the core features of the language.
Prototype Inheritance
Have you ever wonder when we create an array, objects, or function how do we get its method on the fly? 🤔. Even though we don't specify a method like a length, split, splice, reduce, etc all will be available for us to utilize its kind of magic isn't it 🔮!!! Naah its Javascript prototypal inheritance
In JavaScript, every object will be having a special hidden property [[Prototype]]
, that is either null
or references another object
. That object is called a prototype
Let's see with an example
Consider you are manufacturing a laptop (MacbookPro 16") this laptop will have its own features like backlit Keyboard, touch bar, touchid, and many other cool features.
And now every MacbookPro 16" that you manufacture should have these features.
Now let's assume your constructor function will that will produce a new Macbook every time whenever it calls. Now here comes the prototype
which will help to ensure all the manufactured Macbook will have all the features that we want.
The
prototype
for a constructor function will be the constructor of its own function itself
Now the question is. Why are these features stored in an object called __proto__
, and not stored directly as properties of mac
instance?
__proto__
is an object which will be present in every call instance and which will be referring to the prototype
present
In our example mac.__proto__
is referring to the Macbook16.prototype
and thus both hold the same properties whereas Macbook.prototype
is again referring to Object.prototype
thatsol
mac.__proto__
➡️ Macbook.prototype
➡️ Object.prototype
➡️ null
This is nothing but PROTOTYPE INHERITANCE
Some thoughts 💡
- ES6 introduced a constructor function which is synthetic sugar(Shorthand for complex structure) for a traditional class
__proto__
is historical getter and setter for[[prototype]]
proto and prototype
Both __proto__
and prototype
belong to the prototypal inheritance but both are not the same.
__proto__
is a property of class instance
whereas prototype is a property
of class constructor
So far we have seen a prototype inheritance with constructor function and class. So the other way to add a prototype to object is using Object.create()
method.
With this method, we can create a new object and specify what prototype of an object we want
Play with prototype
We can experiment a lot with the prototype
. let's see with one small example
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. if it can't find the property we're trying to access, the engine walks down the prototype chain through the __proto__
property!
__proto__
Prototype methods, objects without The __proto__
is considered outdated and somewhat deprecated (in browser-only part of the JavaScript standard)
Object.create(proto[, descriptors]) creates an empty object with given proto as __proto__ and optional property descriptors
Object.getPrototypeOf(obj) returns the `__proto__` of obj
Object.setPrototypeOf(obj, proto) sets the `__proto__` of obj to proto
Things to consider
- We can save memory by adding properties to the prototype that all instances can share it. instead of creating new properties in each instance
- we should not mess up with instance by manipulating
__proto__
resulting in a lag in performance - We can achieve a circular prototype chain. If we try then JS will throw an error
TypeError: Cyclic __proto__ value