25
Prototypal Inheritance in JavaScript
tl;dr: Understanding Prototypal inheritance, uses & specifics. Composed with code, console & explanatory approach.
Problems are understood crystal clear if seen from a right perspective.
Moving on the same axis: consider a biological perspective for Inheritance concept in Javascript. Let Mike be the father👨 and Joe be his son 👦. As per biology, Joe would inherit some "properties" or an "image" of his father, Mike, unknowingly. This image or "properties" or say versions of the original copy inherited from parent object to child object refers to "Prototypal Inheritance".
...
Javascript is a prototype based language as it enables inheriting the prototypes of an object. Javascript refers it's elements as Objects. A native JS Object have it's own inbuilt bag of properties, and these bag of properties can be inherited by another Object. For example:
console.log(Array.prototype); //brings all basic properties and methods associated with an Array Object and appends it to Array.prototype.
Definitions of terms related to Prototypal Inheritance in JS interviews:
- Prototypal inheritance means objects and methods can be shared, extended, and copied from one Object to another Object.
- A prototype is another object that can be used as a fallback source of properties.
- Prototypal Chain is a lookup mechanism for properties on an object. If an Object's property is accessed, JavaScript initially search the Object itself. If the property isn't found, it will climb all the way up to proto-chain until it is found (or even not).
Some Codewalks for practical learning:
1. Creating a Constructor function and check if it's prototype exist?
Whenever you create a constructor function, a property object called prototype is created automatically and gets attached to the function Object (the Constructor).
Note: This new prototype object also points to, or has an internal-private link to, the native JavaScript Object.
The following example creates a Constructor function, Mike:
function Mike () {
this.name = 'Mike';
this.skill = 'JavaScript';
}
//Mike inherits an Object prototype. The "prototype" gets created with function Mike declaration, automatically.
Mike.hasOwnProperty('prototype');
console.log(Mike.prototype);
//paste above code on console.
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it)~ MDN
2. Adding properties to a function prototype.
The following syntax defines how to assign properties and methods to a functional prototype:
Syntax: function_name.prototype.property_name = property_value;
Mike.prototype.putName = function () {
return 'My name is ' + this.name;
}
console.log(Mike.prototype); //putName method added to Mike prototype
Here, putName method being created as a prototypal method, try comparing it with our previous console output. Any difference?
3. Inheriting Properties from Parent to Child.
Add a "new" keyword to make an instance of the parent Object for inheriting properties.
For example:
var Joe = new Mike();
console.log(Joe); //Son(joe) inherits father prototypal properties
Behind the scenes, when you call: var Joe = new Mike();
JavaScript actually perform below operation:
var Joe = new Object();
Joe.[[Prototype]] = Mike.prototype;
Mike.call(Joe);
4. How do browser find which properties belong to which object?
The browser initially check child Object properties [i.e. own-instance properties] if not found, consequently it searches inherited prototypal properties, if not found, then it traverses proto of the Object to inherit to one level, if not found again, then it traverses proto of the proto till the end of the chain level.
But what's proto ?
_ proto _ is an internal property that ties Object to its prototype.
In layman terms, proto acts as a wormhole that references properties from one Object to another Object, during prototypal chain lookup mechanism.
For example:
Conside the Prototypal chain built using above code:
// Joe ---> Mike ---> Object.prototype ---> null
PI helps in applying DRY principle to Object instances. It also helps in transferring a pool of properties from Parent object to child Object internally. Hence, a inclination towards functional sharing pattern.
...
Some know-hows while dealing with Prototypal Inheritance:
Object.proptotype is supported by various browsers and is very fast. It's also Just-in-time(JIT) Compilation optimizable in nature.
Prototypal Inheritance enables all the properties you define in the parent prototype to be effectively shared by all instances. Changes in the Parent instance properties will be mitigated automatically to all Child Instances.
Null has no prototype, thus ends the prototypal chain. [ P.S: typeof Null= object]
A function in JavaScript always have a default "prototype" property — with one exception: an Arrow function. Arrow function doesn't have a default prototype property.
Making prototypal Code performant. If code is performance constrained, look up time for properties in prototypal chain can have negative effects. As deeper you go in the scope chain, the more computational overheads occurs as [[Prototype]] is looked recursively. To solve the lookup problem, an inbuilt property called as hasOwnProperty can be used. It deals with an Object's own properties, returns a boolean after search and does not traverses whole prototypal chain. As a developer, be aware of the length of your prototypal chains and break them up if necessary to avoid possible performance problems.
Don't extend Object.prototype for adding non-native properties. It breaks encapsulation, and creates a "Monkey Patching" pattern.
Initializations of constructors on parent object might put overload of unwanted methods in child. Be careful while doing it.
Read more about the topic from below resources:
References: MDN, Stack-overflow, V8 -Blog and Internet Blogs.
Prototypal Inheritance was my first </> Article on dev. Any changes or constructive feedback is highly welcome:) Thanks for Reading.❤️
25