. . . don't take them for granted
A brief introduction on
Every object in Javascript, has a special property which is linked to an object, which is referred as the 'Prototype' of an object.
function Foo() {}
Foo.prototype.myName = 'Anirudh';
The term prototype has been used in two ways 😪
I was wrong!😓
For every object which is being created, Javascript internally creates a property named [[Prototype]], and links an object to it.
It is this property which serves as the actual prototype for any object.
The property can also be null.
We can access the property by __proto__/ Object.getPrototypeOf(obj) .
The value of the [[Prototype]] is different for unique type of object in Javascript.
The [[Prototype]] object is used to implement inheritance.
This is a property which, is only created for new function declarations, and for some built-in functions
These .prototype object have a constructor property, which initially points back to the declared function.
All functions in JS, will have their own .prototype property, whose value may differ with the type of function.
It's purpose is to serve as a [[Prototype]] for a different object, or for objects created using new operator on the function declared.
Since, every object in Javascript will have a [[Prototype]], this means, whatever data we go on to declare will have a [[Prototype]] object of their own.
var obj = {
'foo' : 'bar'
};
console.log(obj.__proto__); // Object {}
var arr = [1, 2, 3];
console.log(arr.__proto__); // []
But if we look closely, these are pointing to different objects, for different types
Recall : The value of the [[Prototype]] is different for unique type of object in JS.
which means arrays, numbers, strings, booleans, functions, object literal, etc.. all will have their own [[Prototype]], pointing to some object.
var a = 2;
console.log(a.__proto__); // Number {}
var b = 'foo';
console.log(b.__proto__); // String {}
var obj = {
'foo':'bar'
};
console.log(obj.__proto__); // Object {}
var arr = [];
console.log(arr.__proto__); // []
var bool = true;
console.log(bool.__proto__); // Boolean {}
function Foo(){}
console.log(Foo.__proto__); // function (){}
Recall : The purpose of .prototype object, of every function, is to serve as a [[Prototype]] objfor a different object, or for object created using new operator on the function declared.
The [[Prototype]] for the different types of objects, are pointing nothing to but the .prototype of the in built classes maintained in Javascript like (Function, Number, String, etc. . .), which is Function.prototype, Number.prototype, String.prototype, Array.prototype, Boolean.prototype, Object.prototype, etc . . .
Whenever a function is created in Javascript, Javascript will internally add a property named prototype to the function, and this is only added to function declarations.
console.log(Object.prototype); // Object {}
console.log(Number.prototype); // Number {}
console.log(Function.prototype); // function (){}
console.log(Array.prototype); // []
function Foo(){}
console.log(Foo.prototype); // Object {}
So, if we look at the diagram of how the linking has been done till now for the code, it will look like this.
var obj = { a : 1 };
function Foo(){}
The .prototype has one special property, the constructor property, which 'initially' points back to the function in which .prototype property is present.
Object.prototype.constructor will point back to the Object function, Foo.prototype.constructor will point back to the Foo function, and so on.
console.log(Function.prototype.constructor); // Function
console.log(Foo.prototype.constructor); // Foo
console.log(Number.prototype.constructor); // Number
console.log(Array.prototype.constructor); // Array
console.log(String.prototype.constructor); // String
With the above change, the diagram changes a little.
Since the .prototype is an object the .prototype, will also have it's [[Prototype]], which may point to a different object.
console.log(Function.prototype.__proto__); // Object {}
console.log(Foo.prototype.__proto__); // Object {}
console.log(Number.prototype.__proto__); // Object {}
console.log(Array.prototype.__proto__); // Object {}
console.log(String.prototype.__proto__); // Object {}
console.log(Object.prototype.__proto__); // null
Except, Object.prototype.__proto__ will give us null, indicating that the [[Prototype]] of Object.prototype does not exist.
With the [[Prototype]] in picture for .prototype object, the diagram again undergoes through another modification.
This method of linking an object to the [[Prototype]] of another object, and then so on.. is referred to as Prototype chaining.
The chain needs to end somewhere, and the end of chain is denoted by the fact that [[Prototype]] of Object.prototype is actually null.
This chain is used to look up properties, when the property is not found in the original object.
var fooInstance = new Foo();
It will be "Foo.prototype", and if we, now look at the diagram.
Object.create - accepts an object as first parameter, creates an empty object, links the [[Prototype]] of empty object to the object received.
var obj = {
'foo' : 'bar'
};
var obj2 = Object.create(obj);
console.log(obj2.foo); // 'bar'
function Foo() {}
Foo.prototype.myName = 'Anirudh';
function KidFoo(){}
KidFoo.prototype = Object.create(Foo.prototype);
var kidFooInst = new KidFoo();
console.log(kidFooInst.myName); // 'Anirudh'
console.log(kidFooInst.contructor); // Foo
.prototype object which was initially created for KidFoo, is discarded because it is now replaced with an empty object, whose [[Prototype]] is Foo.prototype
KidFoo.prototype.construtor = KidFoo;
var kidFooInst = new KidFoo();
console.log(kidFooInst.constructor); // KidFoo