This figure again shows that every object has a prototype. Constructor function Foo also has its own
__proto__
which is Function.prototype, a
(number inside the parenthesis () is a 'link' to the code that is written below)
prototype
- an object that consists of:
=> functions (3) of this
particular ConstructorFunction.prototype
(5) that are accessible by each
object (4) created or to-be-created through this constructor function (1)
=> the constructor function itself (1)
=> __proto__
of this particular object (prototype object)
__proto__
(dandor proto?) - a link BETWEEN any object (2) created through a particular constructor function (1), AND the prototype object's properties (5) of that constructor THAT allows each created object (2) to have access to the prototype's functions and methods (4) (__proto__
is by default included in every single object in JS)
1.
function Person (name, age) {
this.name = name;
this.age = age;
}
2.
var John = new Person(‘John’, 37);
// John is an object
3.
Person.prototype.getOlder = function() {
this.age++;
}
// getOlder is a key that has a value of the function
4.
John.getOlder();
5.
Person.prototype;
There is only one object that is used for protypal chaining. This object obviously has a name and a value: __proto__
is its name, and prototype
is its value. That's all.
to make it even easier to grasp, look at the diagram on the top of this post (Diagram by dmitry soshnikov), you'll never find __proto__
points to something else other than prototype
as its value.
The gist is this: __proto__
is the name that references the prototypal object, and prototype
is the actual prototypal object.
It's like saying:
let x = {name: 'john'};
x
is the object name (pointer), and {name: 'john'}
is the actual object (data value).
NOTE: this just a massively simplified hint on how they are related on a high level.
Update: Here is a simple concrete javascript example for better illustration:
let x = new String("testing") // Or any other javascript object you want to create
Object.getPrototypeOf(x) === x.__proto__; // true
This means that when Object.getPrototypeOf(x)
gets us the actual value of x
(which is its prototype), is exactly what the __proto__
of x
is pointing to. Therefore __proto__
is indeed pointing to the prototype of x
. Thus __proto__
references x
(pointer of x
), and prototype
is the value of x
(its prototype).
I hope it's a bit clear now.
A nice way to think of it is...
prototype
is used by constructor()
functions. It should've really been called something like, "prototypeToInstall"
, since that's what it is.
and __proto__
is that "installed prototype" on an object (that was created/installed upon the object from said constructor()
function)
To put it simply:
> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true
This allows you to attach properties to X.prototype AFTER objects of type X has been instantiated, and they will still get access to those new properties through the __proto__ reference which the Javascript-engine uses to walk up the prototype chain.
In JavaScript, a function can be used as a constructor. That means we can create objects out of them using the new keyword. Every constructor function comes with a built-in object chained with them. This built-in object is called a prototype. Instances of a constructor function use __proto__ to access the prototype property of its constructor function.
First we created a constructor: function Foo(){}
. To be clear, Foo is just another function. But we can create an object from it with the new keyword. That's why we call it the constructor function
Every function has a unique property which is called the prototype property. So, Constructor function Foo
has a prototype property which points to its prototype, which is Foo.prototype
(see image).
Constructor functions are themselves a function which is an instance of a system constructor called the [[Function]] constructor. So we can say that function Foo
is constructed by a [[Function]] constructor. So, __proto__
of our Foo function
will point to the prototype of its constructor, which is Function.prototype
.
Function.prototype
is itself is nothing but an object which is constructed from another system constructor called [[Object]]
. So, [[Object]]
is the constructor of Function.prototype
. So, we can say Function.prototype
is an instance of [[Object]]
. So __proto__
of Function.prototype
points to Object.prototype
.
Object.prototype
is the last man standing in the prototype chain. I mean it has not been constructed. It's already there in the system. So its __proto__
points to null
.
Now we come to instances of Foo
. When we create an instance using new Foo()
, it creates a new object which is an instance of Foo
. That means Foo
is the constructor of these instances. Here we created two instances (x and y). __proto__
of x and y thus points to Foo.prototype
.
I've made for myself a small drawing that represents the following code snippet:
var Cat = function() {}
var tom = new Cat()
I have a classical OO background, so it was helpful to represent the hierarchy in this manner. To help you read this diagram, treat the rectangles in the image as JavaScript objects. And yes, functions are also objects. ;)
Objects in JavaScript have properties and __proto__
is just one of them.
The idea behind this property is to point to the ancestor object in the (inheritance) hierarchy.
The root object in JavaScript is Object.prototype
and all other objects are descendants of this one. The __proto__
property of the root object is null
, which represents the end of inheritance chain.
You'll notice that prototype
is a property of functions. Cat
is a function, but also Function
and Object
are (native) functions. tom
is not a function, thus it does not have this property.
The idea behind this property is to point to an object which will be used in the construction, i.e. when you call the new
operator on that function.
Note that prototype objects (yellow rectangles) have another property called
constructor
which points back to the respective function object. For brevity reasons this was not depicted.
Indeed, when we create the tom
object with new Cat()
, the created object will have the __proto__
property set to the prototype
object of the constructor function.
In the end, let us play with this diagram a bit. The following statements are true:
tom.__proto__
property points to the same object as Cat.prototype
.
Cat.__proto__
points to the Function.prototype
object, just like Function.__proto__
and Object.__proto__
do.
Cat.prototype.__proto__
and tom.__proto__.__proto__
point to the same object and that is Object.prototype
.
Cheers!