This figure again shows that every object has a prototype. Constructor function Foo also has its own
__proto__
which is Function.prototype, a
I happen to be learning prototype from You Don't Know JS: this & Object Prototypes, which is a wonderful book to understand the design underneath and clarify so many misconceptions (that's why I'm trying to avoid using inheritance and things like instanceof
).
But I have the same question as people asked here. Several answers are really helpful and enlightening. I'd also love to share my understandings.
Objects in JavaScript have an internal property, denoted in the specification as[[Prototype]]
, which is simply a reference to another object. Almost all objects are given a non-null
value for this property, at the time of their creation.
via __proto__
or Object.getPrototypeOf
var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true
function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype
prototype
?prototype
is an object automatically created as a special property of a function, which is used to establish the delegation (inheritance) chain, aka prototype chain.
When we create a function a
, prototype
is automatically created as a special property on a
and saves the function code on as the constructor
on prototype
.
function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true
I'd love to consider this property as the place to store the properties (including methods) of a function object. That's also the reason why utility functions in JS are defined like Array.prototype.forEach()
, Function.prototype.bind()
, Object.prototype.toString().
Why to emphasize the property of a function?
{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}
// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();
So, Arary
, Function
, Object
are all functions. I should admit that this refreshes my impression on JS. I know functions are first-class citizen in JS but it seems that it is built on functions.
__proto__
and prototype
?__proto__
a reference works on every object to refer to its [[Prototype]]
property.
prototype
is an object automatically created as a special property of a function, which is used to store the properties (including methods) of a function object.
With these two, we could mentally map out the prototype chain. Like this picture illustrates:
function Foo() {}
var b = new Foo();
b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
This is a very important question relevant to anyone who wants to understand prototypical inheritance. From what I understand, prototype is assigned by default when an object is created with new from a function because Function has prototype object by definition:
function protofoo(){
}
var protofoo1 = new protofoo();
console.log(protofoo.prototype.toString()); //[object Object]
When we create an ordinary object without new, ie explicitly from a function, it doesn't have prototype but it has an empty proto which can be assigned a prototype.
var foo={
check: 10
};
console.log(foo.__proto__); // empty
console.log(bar.prototype); // TypeError
foo.__proto__ = protofoo1; // assigned
console.log(foo.__proto__); //protofoo
We can use Object.create to link an object explicitly.
// we can create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.fooprops= "We checking prototypes";
console.log(bar.__proto__); // "foo"
console.log(bar.fooprops); // "We checking prototypes"
console.log(bar.check); // 10 is delegated to `foo`
I know, I am late but let me try to simplify it.
Let us say there is a function
function Foo(message){
this.message = message ;
};
console.log(Foo.prototype);
Foo function will have a prototype object linked. So,Whenever we create a function in JavaScript, it always has a prototype object linked to it.
Now let us go ahead and create two objects using the function Foo.
var a = new Foo("a");
var b = new Foo("b");
console.log(a.message);
console.log(b.message);
Now, Foo.prototype, a.__proto__, and b.__proto__ all denotes same object.
b.__proto__ === Object.getPrototypeOf(a);
a.__proto__ === Foo.prototype;
a.constructor.prototype === a.__proto__;
all of above would return true.
As we know, in JavaScript properties can be added dynamically. We can add property to object
Foo.prototype.Greet = function(){
console.log(this.message);
}
a.Greet();//a
b.Greet();//b
a.constructor.prototype.Greet();//undefined
As you see we added Greet() method in Foo.prototype but it is accessible in a and b or any other object which is constructed using Foo.
While executing a.Greet(), JavaScript will first search Greet in object a on property list. On not finding , it will go up in __proto__ chain of a. Since a.__proto__ and Foo.prototype is same object, JavaScript will find Greet() method and execute it.
I hope, now prototype and __proto__ is simplified a bit.
!!!THIS IS THE BEST EXPLANATION IN THE WORLD!!!!!
var q = {}
var prototype = {prop: 11}
q.prop // undefined
q.__proto__ = prototype
q.prop // 11
in function constructors javascript engine call this q.__proto__ = prototype
automatically when we write new Class
, and in to the __proto__
prop set Class.prototype
function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new
var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999
Enjoy %)
prototype is a property of a Function. It is the blueprint for creating objects by using that (constructor) function with new keyword.
__proto__
is used in the lookup chain to resolve methods, properties. when an object is created (using constructor function with new keyword), __proto__
is set to (Constructor) Function.prototype
function Robot(name) {
this.name = name;
}
var robot = new Robot();
// the following are true
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype
Imagine there is an imaginary class (blueprint/coockie cutter) associated with function. That imaginary class is used to instantiate objects. prototype
is the extention mechanism (extention method in C#, or Swift Extension) to add things to that imaginary class.
function Robot(name) {
this.name = name;
}
The above can be imagined as:
// imaginary class
class Robot extends Object{
static prototype = Robot.class
// Robot.prototype is the way to add things to Robot class
// since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
}
So,
var robot = new Robot();
robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype
Now adding method to the prototype
of Robot:
Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)
The above can be imagined as extension of Robot class:
// Swift way of extention
extension Robot{
function move(x, y){
Robot.position.x = x; Robot.position.y = y
}
}
Which in turn,
// imaginary class
class Robot{
static prototype = Robot.class // Robot.prototype way to extend Robot class
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
// added by prototype (as like C# extension method)
function move(x, y){
Robot.position.x = x; Robot.position.y = y
};
}
What about using __proto__
for static methods?
function Foo(name){
this.name = name
Foo.__proto__.collection.push(this)
Foo.__proto__.count++
}
Foo.__proto__.count=0
Foo.__proto__.collection=[]
var bar = new Foo('bar')
var baz = new Foo('baz')
Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined