Inheritance is based on prototype(s) . Prototype is an object that every function has as an accessible .prototype property which you can clearly see on user-agent (browser's) console (personally I use Chrome) . Initially every prototype object is composed of constructor
and __proto__ : Object
. Do NOT get confused : the __proto__ : Object
& the aforementioned prototype's object itself – these two works hand in hand , but are definitely NOT the same "thing" ! Function body declared within the Function's keyword this
is not visible until instantiated , conversely the function body declared via .prototype
property is visible even before instantiated & will be shared across all the instances – most often we use .prototype to extend (augment) some existing built-in such as Array.prototype . Roughly said .prototype property hooks in the internal [[prototype]]
mechanism for "inheritance" . When it comes about definition of "instantiation" i.e. is the process of making blueprints come true object instances (templates, constructors – are synonyms in such context) .
Perfect visual example all credits to Dmitri Pavlutin :
Instantiation process is a two step process : 1) write a function constructor (a.k.a. class as syntactic sugar since ES6+) & 2) use a keyword new
to work with constructor's inner logic i.e. this.
Proof for "constructor is a function":
function _Class(){}
typeof _Class.prototype.constructor === 'function' // true
new _Class/*(args)*/ // note : parenthesis are optional if...
// ...no arguments intended to pass ;
To understand better the idea behind __proto__
, examine the following
// NOTE: to get best programming experience , copy paste the following to ones browser
// TIP : you can invoke console by e.g. navigating to about:blank on Chrome & Ctrl + Shift + I (Windows)
function Home() {
this.is = "my home";
}
// TL;DR : __proto__ targets to parent.prototype upon which the resulting, in this case , Home.prototype is based on :
// think of __proto__ as a taxi moving towards to the kernel (core) as of Object.prototype
// think of .prototype as a taxi moving from kernel (core) towards outside the city where you built one's own cozy e.g. Home.prototype
Home.constructor.__proto__ === Function.prototype; // true # constructor is a core for function, roughly said – function is a constructor itself !
Home.prototype.__proto__ === Object.prototype; // true # function is an object , everything is an object in JS under the hood !
// the last one also could be compared truthy as so :
Object.getPrototypeOf(Home).__proto__ === Object.prototype; // true # same idea
// see for (cont'd) below...
Also as a helper consider this simplified .prototype vs. proto diagram made by me (powered by @jgraph/drawio)
However, if instantiated & assigned to variable (reference) , __proto__
may refer to a different stuff , let's see in action :
// (cont'd)
let house1 = new Home(/* args (if any) */);
console.log(house1); // Home {is: 'my home'}
console.log(house1.__proto__); // === Home.prototype
console.log(house1.__proto__.__proto__); // === Object.prototype
console.log(house1.__proto__.__proto__.__proto__); // same as (house1.__proto__.__proto__.__proto__ && Object.prototype.__proto__) === null – End of the road – Object.prototype is a basis for Prototype inheritance chaining .
To conclude : as mentioned above , within given example with a taxi, – __proto__
digs deeper i.e. moves towards the core of Object.prototype , whilst .prototype does opposite – search wider (gets outside, away from the core, augments, extends)
LIFE TIP : in my native spoken language i.e. Lithuanian "proto" means "of mind" , if it helps making it meaningful in any possible way , then let it be , if not choose your own suitable way . Personally to me, if things has some proper meaning – it's a life saver!
That's it ! if any typos found or suggestion could be made or maybe you want to clarify something , please leave a comment in the comment section below . Thanks for reading & see you in a next one!
Top comments (0)