'__proto__ VS. prototype in JavaScript
This figure again shows that every object has a prototype. Constructor function Foo also has its own
__proto__
which is Function.prototype, and which in turn also references via its__proto__
property again to the Object.prototype. Thus, repeat, Foo.prototype is just an explicit property of Foo which refers to the prototype of b and c objects.
var b = new Foo(20);
var c = new Foo(30);
What are the differences between __proto__
and prototype
?
The figure was taken from dmitrysoshnikov.com.
Note: there is now a 2nd edition (2017) to the above 2010 article.
Solution 1:[1]
__proto__
is the actual object that is used in the lookup chain to resolve methods, etc. prototype
is the object that is used to build __proto__
when you create an object with new
:
( new Foo ).__proto__ === Foo.prototype
( new Foo ).prototype === undefined
Solution 2:[2]
prototype
is a property of a Function object. It is the prototype of objects constructed by that function.
__proto__
is an internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(obj)
method, though the de facto standard __proto__
is quicker.
You can find instanceof
relationships by comparing a function's prototype
to an object's __proto__
chain, and you can break these relationships by changing prototype
.
function Point(x, y) {
this.x = x;
this.y = y;
}
var myPoint = new Point();
// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;
Here Point
is a constructor function, it builds an object (data structure) procedurally. myPoint
is an object constructed by Point()
so Point.prototype
gets saved to myPoint.__proto__
at that time.
Solution 3:[3]
prototype
property is created when a function is declared.
For instance:
function Person(dob){
this.dob = dob
};
Person.prototype
property is created internally once you declare above function.
Many properties can be added to the Person.prototype
which are shared by Person
instances created using new Person()
.
// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob};
It is worth noting that Person.prototype
is an Object
literal by default (it can be changed as required).
Every instance created using new Person()
has a __proto__
property which points to the Person.prototype
. This is the chain that is used to traverse to find a property of a particular object.
var person1 = new Person(somedate);
var person2 = new Person(somedate);
creates 2 instances of Person
, these 2 objects can call age
method of Person.prototype
as person1.age
, person2.age
.
In the above picture from your question, you can see that Foo
is a Function Object
and therefore it has a __proto__
link to the Function.prototype
which in turn is an instance of Object
and has a __proto__
link to Object.prototype
. The proto link ends here with __proto__
in the Object.prototype
pointing to null
.
Any object can have access to all the properties in its proto chain as linked by __proto__
, thus forming the basis for prototypal inheritance.
__proto__
is not a standard way of accessing the prototype chain, the standard but similar approach is to use Object.getPrototypeOf(obj)
.
Below code for instanceof
operator gives a better understanding:
object instanceof
Class operator returns true
when an object is an instance of a Class, more specifically if Class.prototype
is found in the proto chain of that object then the object is an instance of that Class.
function instanceOf(Func){
var obj = this;
while(obj !== null){
if(Object.getPrototypeOf(obj) === Func.prototype)
return true;
obj = Object.getPrototypeOf(obj);
}
return false;
}
The above method can be called as: instanceOf.call(object, Class)
which return true if object is instance of Class.
Solution 4:[4]
To explain let us create a function
function a (name) {
this.name = name;
}
When JavaScript executes this code, it adds prototype
property to a
, prototype
property is an object with two properties to it:
constructor
__proto__
So when we do
a.prototype
it returns
constructor: a // function definition
__proto__: Object
Now as you can see constructor
is nothing but the function a
itself
and __proto__
points to the root level Object
of JavaScript.
Let us see what happens when we use a
function with new
key word.
var b = new a ('JavaScript');
When JavaScript executes this code it does 4 things:
- It creates a new object, an empty object // {}
- It creates
__proto__
onb
and makes it point toa.prototype
sob.__proto__ === a.prototype
- It executes
a.prototype.constructor
(which is definition of functiona
) with the newly created object (created in step#1) as its context (this), hence thename
property passed as 'JavaScript' (which is added tothis
) gets added to newly created object. - It returns newly created object in (created in step#1) so var
b
gets assigned to newly created object.
Now if we add a.prototype.car = "BMW"
and do
b.car
, the output "BMW" appears.
this is because when JavaScript executed this code it searched for car
property on b
, it did not find then JavaScript used b.__proto__
(which was made to point to 'a.prototype' in step#2) and finds car
property so return "BMW".
Solution 5:[5]
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)
Solution 6:[6]
Prototype VS. __proto__ VS. [[Prototype]]
When creating a function, a property object called prototype is being created automatically (you didn't create it yourself) and is being 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.
Example:
function Foo () {
this.name = 'John Doe';
}
// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true
// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
return 'My name is ' + this.name;
}
If you create a new object out of Foo
using the new
keyword, you are basically creating (among other things) a new object that has an internal or private link to the function Foo
's prototype we discussed earlier:
var b = new Foo();
b.[[Prototype]] === Foo.prototype // true
The private linkage to that function's object called double brackets prototype or just
[[Prototype]]
. Many browsers are providing us a public linkage to it that called __proto__
!
To be more specific, __proto__
is actually a getter function that belong to the native JavaScript Object. It returns the internal-private prototype linkage of whatever the this
binding is (returns the [[Prototype]]
of b
):
b.__proto__ === Foo.prototype // true
It is worth noting that starting of ECMAScript5
, you can also use the getPrototypeOf method to get the internal private linkage:
Object.getPrototypeOf(b) === b.__proto__ // true
NOTE: this answer doesn't intend to cover the whole process of creating new objects or new constructors, but to help better understand what is
__proto__
, prototype
and [[Prototype]]
and how it works.
Solution 7:[7]
To make it a little bit clear in addition to above great answers:
function Person(name){
this.name = name
};
var eve = new Person("Eve");
eve.__proto__ == Person.prototype //true
eve.prototype //undefined
Instances have __proto__, classes have prototype.
Solution 8:[8]
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 functionEvery 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 isFoo.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 ourFoo function
will point to the prototype of its constructor, which isFunction.prototype
.Function.prototype
is itself is nothing but an object which is constructed from another system constructor called[[Object]]
. So,[[Object]]
is the constructor ofFunction.prototype
. So, we can sayFunction.prototype
is an instance of[[Object]]
. So__proto__
ofFunction.prototype
points toObject.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 tonull
.Now we come to instances of
Foo
. When we create an instance usingnew Foo()
, it creates a new object which is an instance ofFoo
. That meansFoo
is the constructor of these instances. Here we created two instances (x and y).__proto__
of x and y thus points toFoo.prototype
.
Solution 9:[9]
Summary:
The __proto__
property of an object is a property that maps to the prototype
of the constructor function of the object. In other words:
instance.__proto__ === constructor.prototype // true
This is used to form the prototype
chain of an object. The prototype
chain is a lookup mechanism for properties on an object. If an object's property is accessed, JavaScript will first look on the object itself. If the property isn't found there, it will climb all the way up to protochain
until it is found (or not)
Example:
function Person (name, city) {
this.name = name;
}
Person.prototype.age = 25;
const willem = new Person('Willem');
console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor
console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function
Our first log results to true
, this is because as mentioned the __proto__
property of the instance created by the constructor refers to the prototype
property of the constructor. Remember, in JavaScript, functions are also Objects. Objects can have properties, and a default property of any function is one property named prototype.
Then, when this function is utilized as a constructor function, the object instantiated from it will receive a property called __proto__
. And this __proto__
property refers to the prototype
property of the constructor function (which by default every function has).
Why is this useful?
JavaScript has a mechanism when looking up properties on Objects
which is called 'prototypal inheritance', here is what it basically does:
- First, it's checked if the property is located on the Object itself. If so, this property is returned.
- If the property is not located on the object itself, it will 'climb up the protochain'. It basically looks at the object referred to by the
__proto__
property. There, it checks if the property is available on the object referred to by__proto__
. - If the property isn't located on the
__proto__
object, it will climb up the__proto__
chain, all the way up toObject
object. - If it cannot find the property anywhere on the object and its
prototype
chain, it will returnundefined
.
For example:
function Person (name) {
this.name = name;
}
let mySelf = new Person('Willem');
console.log(mySelf.__proto__ === Person.prototype);
console.log(mySelf.__proto__.__proto__ === Object.prototype);
Solution 10:[10]
'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true
In JavaScript, Every object(function is object too!) has a __proto__
property, the property is reference to its prototype.
When we use the new
operator with a constructor to create a new object,
the new object's __proto__
property will be set with constructor's prototype
property,
then the constructor will be call by the new object,
in that process "this" will be a reference to the new object in the constructor scope, finally return the new object.
Constructor's prototype is __proto__
property, Constructor's prototype
property is work with the new
operator.
Constructor must be a function, but function not always is constructor even if it has prototype
property.
Prototype chain actually is object's __proto__
property to reference its prototype,
and the prototype's __proto__
property to reference the prototype's prototype, and so on,
until to reference Object's prototype's __proto__
property which is reference to null.
For example:
console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A
[[Prototype]]
and __proto__
property actually is same thing.
We can use Object's getPrototypeOf method to get something's prototype.
console.log(Object.getPrototypeOf(a) === a.__proto__); // true
Any function we written can be use to create an object with the new
operator,
so anyone of those functions can be a constructor.
Solution 11:[11]
I think you need to know the difference between __proto__ , [[prototype]] and prototype.
The accepted answer is helpful, but it might imply (imperfectly) that __proto__
is something only relevant to objects created using new
on a constructor function, which is not true.
To be more precise: __proto__
exists on EVERY object.
But what is
__proto__
at all?- Well, it is an object referencing another object which is also a property of all objects, called
[[prototype]]
. - It's worth mentioning that
[[prototype]]
is something that JavaScript handles internally and is inaccessible to the developer.
- Well, it is an object referencing another object which is also a property of all objects, called
Why would we need a reference object to the property
[[prototype]]
(of all objects)?- Because JavaScript doesn't want to allow getting / setting the
[[prototype]]
directly, so it allows it through a middle layer which is__proto__
. So you can think of__proto__
as a getter/setter of the[[prototype]]
property.
- Because JavaScript doesn't want to allow getting / setting the
What is
prototype
then?It is something specific to functions(Initially defined in
Function
, i.e,Function.prototype
and then prototypically inherited by newly created functions, and then again those functions give it to their children, forming a chain of prototypical inheritance).JavaScript uses a parent function's
prototype
to set its child functions'[[prototype]]
when that parent function is run withnew
(remember we said all objects have[[prototype]]
? well, functions are objects too, so they have[[prototype]]
as well). So when the[[prototype]]
of a function(child) is set to theprototype
of another function(parent), you will have this in the end:let child = new Parent(); child.__proto__ === Parent.prototype // --> true.
(Remember
child.[[prototype]]
is inaccessible, so we checked it using__proto__
.)
Notice 1: Whenever a property is not in the child, its __proto__
will be searched "implicitly". So for instance, if child.myprop
returns a value, you can't say whether "myprop" was a property of the child, or of one of its parents' prototypes. This also means that you never need to do something like: child.__proto__.__proto__.myprop
on your own, just child.myprop
will do that for you automatically.
Notice 2: Even if the parent's prototype has items in it, the child's own prototype
will be an empty object initially. You can add items to it or remove from it manually though, if you want to further extend the inhertance chain(add child[ren] to the child). Or it can be manipulated implicitly, e.g., using the class syntax.)
Notice 3: In case you need to set/get the [[prototype]]
yourself, using __proto__
is a bit outdated and modern JavaScript suggests using Object.setPrototypeOf
and Object.getPrototypeOf
instead.
Solution 12:[12]
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.
What is a prototype?
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.
How to get an object's prototype?
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
What is the 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.
What's the difference between __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
Solution 13:[13]
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 we have two objects, object a and object b. Both are created using constructor Foo. Keep in mind constructor is just a word here.
- Object a and b both have a copy of message property.
- These two objects a and b are linked to prototype object of constructor Foo.
- On objects a and b, we can access Foo prototype using __proto__ property in all browsers and in IE we can use Object.getPrototypeOf(a) or Object.getPrototypeOf(b)
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.
Solution 14:[14]
Another good way to understand it:
var foo = {}
/*
foo.constructor is Object, so foo.constructor.prototype is actually
Object.prototype; Object.prototype in return is what foo.__proto__ links to.
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);
Only after IE11 __proto__
is supported. Before that version, such as IE9, you could use the constructor
to get the __proto__
.
Solution 15:[15]
prototype
prototype is a property of a Function. It is the blueprint for creating objects by using that (constructor) function with new keyword.
__proto__
__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
Here is my (imaginary) explanation to clear the confusion:
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
};
}
Solution 16:[16]
[[Prototype]] :
[[Prototype]] is an internal hidden property of objects in JS and it is a reference to another object. Every object at the time of creation receives a non-null value for [[Prototype]]. Remember [[Get]] operation is invoked when we reference a property on an object like, myObject.a. If the object itself has a property, a on it then that property will be used.
let myObject= {
a: 2
};
console.log(myObject.a); // 2
But if the object itself directly does not have the requested property then [[Get]] operation will proceed to follow the [[Prototype]] link of the object. This process will continue until either a matching property name is found or the [[Prototype]] chain ends(at the built-in Object.prototype). If no matching property is found then undefined will be returned. Object.create(specifiedObject) creates an object with the [[Prototype]] linkage to the specified object.
let anotherObject= {
a: 2
};
// create an object linked to anotherObject
let myObject= Object.create(anotherObject);
console.log(myObject.a); // 2
Both for..in loop and in operator use [[Prototype]] chain lookup process. So if we use for..in loop to iterate over the properties of an object then all the enumerable properties which can be reached via that object's [[Prototype]] chain also will be enumerated along with the enumerable properties of the object itself. And when using in operator to test for the existence of a property on an object then in operator will check all the properties via [[Prototype]] linkage of the object regardless of their enumerability.
// for..in loop uses [[Prototype]] chain lookup process
let anotherObject= {
a: 2
};
let myObject= Object.create(anotherObject);
for(let k in myObject) {
console.log("found: " + k); // found: a
}
// in operator uses [[Prototype]] chain lookup process
console.log("a" in myObject); // true
.prototype :
.prototype is a property of functions in JS and it refers to an object having constructor property which stores all the properties(and methods) of the function object.
let foo= function(){}
console.log(foo.prototype);
// returns {constructor: f} object which now contains all the default properties
foo.id= "Walter White";
foo.job= "teacher";
console.log(foo.prototype);
// returns {constructor: f} object which now contains all the default properties and 2 more properties that we added to the fn object
/*
{constructor: f}
constructor: f()
id: "Walter White"
job: "teacher"
arguments: null
caller: null
length: 0
name: "foo"
prototype: {constructor: f}
__proto__: f()
[[FunctionLocation]]: VM789:1
[[Scopes]]: Scopes[2]
__proto__: Object
*/
But normal objects in JS does not have .prototype property. We know Object.prototype is the root object of all the objects in JS. So clearly Object is a function i.e. typeof Object === "function" . That means we also can create object from the Object function like, let myObj= new Object( ). Similarly Array, Function are also functions so we can use Array.prototype, Function.prototype to store all the generic properties of arrays and functions. So we can say JS is built on functions.
{}.prototype; // SyntaxError: Unexpected token '.'
(function(){}).prototype; // {constructor: f}
Also using new operator if we create objects from a function then internal hidden [[Prototype]] property of those newly created objects will point to the object referenced by the .prototype property of the original function. In the below code, we have created an object, a from a fn, Letter and added 2 properties one to the fn object and another to the prototype object of the fn. Now if we try to access both of the properties on the newly created object, a then we only will be able to access the property added to the prototype object of the function. This is because the prototype object of the function is now on the [[Prototype]] chain of the newly created object, a.
let Letter= function(){}
let a= new Letter();
Letter.from= "Albuquerque";
Letter.prototype.to= "New Hampshire";
console.log(a.from); // undefined
console.log(a.to); // New Hampshire
.__proto__:
.__proto__
is a property of objects in JS and it references the another object in the [[Prototype]] chain. We know [[Prototype]] is an internal hidden property of objects in JS and it references another object in the [[Prototype]] chain. We can get or set the object referred by the internal [[Prototype]] property in 2 ways
Object.getPrototypeOf(obj) / Object.setPrototypeOf(obj)
obj.__proto__
We can traverse the [[Prototype]] chain using: .__proto__.__proto__. .
. Along with .constructor, .toString( ), .isPrototypeOf( ) our dunder proto property (__proto__
) actually exists on the built-in Object.prototype root object, but available on any particular object. Our .__proto__
is actually a getter/setter. Implementation of .__proto__
in Object.prototype is as below :
Object.defineProperty(Object.prototype, "__proto__", {
get: function() {
return Object.getPrototypeOf(this);
},
set: function(o) {
Object.setPrototypeOf(this, o);
return o;
}
});
To retrieve the value of obj.__proto__
is like calling, obj.__proto__()
which actually returns the calling of the getter fn, Object.getPrototypeOf(obj)
which exists on Object.prototype object. Although .__proto__
is a settable property but we should not change [[Prototype]] of an already existing object because of performance issues.
Using new operator if we create objects from a function then internal hidden [[Prototype]] property of those newly created objects will point to the object referenced by the .prototype property of the original function. Using .__proto__
property we can access the other object referenced by internal hidden [[Prototype]] property of the object. But __proto__
is not the same as [[Prototype]] rather a getter/setter for it. Consider below code :
let Letter= function() {}
let a= new Letter();
let b= new Letter();
let z= new Letter();
// output in console
a.__proto__ === Letter.prototype; // true
b.__proto__ === Letter.prototype; // true
z.__proto__ === Letter.prototype; // true
Letter.__proto__ === Function.prototype; // true
Function.prototype.__proto__ === Object.prototype; // true
Letter.prototype.__proto__ === Object.prototype; // true
Solution 17:[17]
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.
Solution 18:[18]
Prototype or Object.prototype is a property of an object literal. It represents the Object prototype object which you can override to add more properties or methods further along the prototype chain.
__proto__ is an accessor property (get and set function) that exposes the internal prototype of an object thru which it is accessed.
References:
Solution 19:[19]
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 asCat.prototype
.Cat.__proto__
points to theFunction.prototype
object, just likeFunction.__proto__
andObject.__proto__
do.Cat.prototype.__proto__
andtom.__proto__.__proto__
point to the same object and that isObject.prototype
.
Cheers!
Solution 20:[20]
Explanatory example:
function Dog(){}
Dog.prototype.bark = "woof"
let myPuppie = new Dog()
now, myPupppie has __proto__
property which points to Dog.prototype.
> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}
but myPuppie does NOT have a prototype property.
> myPuppie.prototype
>> undefined
So, __proto__
of mypuppie is the reference to the .prototype property of constructor function that was used to instantiate this object (and the current myPuppie object has "delegates to" relationship to this __proto__
object), while .prototype property of myPuppie is simply absent (since we did not set it).
Good explanation by MPJ here: proto vs prototype - Object Creation in JavaScript
Solution 21:[21]
DEFINITIONS
(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)
CODE CLARIFICATION
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;
Solution 22:[22]
I'll try a 4th grade explanation:
Things are very simple. A prototype
is an example of how something should be built. So:
I'm a
function
and I build new objects similar to myprototype
I'm an
object
and I was built using my__proto__
as an example
proof:
function Foo() { }
var bar = new Foo()
// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true
// bar is an instance - it does not know how to create objects
bar.prototype // => undefined
Solution 23:[23]
Every function you create has a property called prototype
, and it starts off its life as an empty object. This property is of no use until you use this function as constructor function i.e. with the 'new' keyword.
This is often confused with the __proto__
property of an object. Some might get confused and except that the prototype
property of an object might get them the proto of an object. But this is not case. prototype
is used to get the __proto__
of an object created from a function constructor.
In the above example:
function Person(name){
this.name = name
};
var eve = new Person("Eve");
console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__
I hope it makes sense.
Solution 24:[24]
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
Solution 25:[25]
(function(){
let a = function(){console.log(this.b)};
a.prototype.b = 1;
a.__proto__.b = 2;
let q = new a();
console.log(a.b);
console.log(q.b)
})()
Try this code to understand
Solution 26:[26]
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.
Solution 27:[27]
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`
Solution 28:[28]
so many good answers exist for this question, but for recap and compact form of answer that have good details I add the following:
the first thing that we must consider is when JS was invented, computers have very low memory, so if we need a process for creating new object types, we must consider memory performance.
so they located methods that object created from that specific object type
need, on the separate part of memory instead of every time we create a new object, store methods besides the object.
so if we reinvent the new
operator and constructor
function concept with JS's new features we have these steps:
- and empty object. (that will be the final result of instantiation of object type)
let empty={}
- we already know that for memory performance reasons all the methods that are needed for instances of an
object type
are located on the constructor function'sprototype
property. (functions are also objects so they can have properties) so we reference theempty
object's__protp__
to the location where those methods exist. (we consider the function that we use conceptually as the constructor, named constructor.
empty.__proto__ = constructor.prototype
- we must initialize object type values.
in JS function are disconnected from objects. with dot notation or methods like
bind
call
apply
that function objects have we must tell "what is thethis
context of the function".
let newFunc = constructor.bind(empty)
- now we have a new function that has an
empty
object asthis
context. after execution of this function. theempty
object will be filled, and the result of instantiation of type object will be thisempty
object if definedconstructor
function doesn't return(as if that will be the result of the process)
so as you see __proto__
is a property of objects that refers to other objects(in JS functions are also object) prototype
object property which consisted of properties that use across instances of a specific object type
.
as you can guess from the phrase, functions are objects
, functions also have __proto__
property so they can refer to other object's prototype
properties. this is how prototype inheritance
is implemented.
Solution 29:[29]
__proto__
is the base to construct prototype
and a constructor function eg: function human(){}
has prototype
which is shared via __proto__
in the new instance of the constructor function. A more detailed read here
Solution 30:[30]
As this rightly stated
__proto__
is the actual object that is used in the lookup chain to resolve methods, etc. prototype is the object that is used to build__proto__
when you create an object with new:( new Foo ).__proto__ === Foo.prototype; ( new Foo ).prototype === undefined;
We can further note that __proto__
property of an object created using function constructor points towards the memory location pointed towards by prototype property of that respective constructor.
If we change the memory location of prototype of constructor function, __proto__
of derived object will still continue to point towards the original address space. Therefore to make common property available down the inheritance chain, always append property to constructor function prototype, instead of re-initializing it (which would change its memory address).
Consider the following example:
function Human(){
this.speed = 25;
}
var himansh = new Human();
Human.prototype.showSpeed = function(){
return this.speed;
}
himansh.__proto__ === Human.prototype; //true
himansh.showSpeed(); //25
//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}
//himansh.__proto__ will still continue to point towards the same original memory location.
himansh.__proto__ === Human.prototype; //false
himansh.showSpeed(); //25
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow