__proto__ VS. prototype in JavaScript

249,822

Solution 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

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

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

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:

  1. constructor
  2. __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:

  1. It creates a new object, an empty object // {}
  2. It creates __proto__ on b and makes it point to a.prototype so b.__proto__ === a.prototype
  3. It executes a.prototype.constructor (which is definition of function a ) with the newly created object (created in step#1) as its context (this), hence the name property passed as 'JavaScript' (which is added to this) gets added to newly created object.
  4. 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

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)

Share:
249,822
0x90
Author by

0x90

echo \[q\]sa\[ln0=aln256%Pln256/snlbx\]sb3135071790101768542287578439snlbxq|dc

Updated on April 15, 2022

Comments

  • 0x90
    0x90 about 2 years

    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?

    enter image description here

    The figure was taken from dmitrysoshnikov.com.

    Note: there is now a 2nd edition (2017) to the above 2010 article.

    • Bergi
      Bergi about 10 years
    • Mike Lippert
      Mike Lippert almost 10 years
      I think top-down or bottom-up is a matter of preference. I actually prefer it this way, so I can trace down the diagram until I find where something comes from.
    • John Sonderson
      John Sonderson over 9 years
      I like how JavaScript uses prototypical inheritance to resolve y.constructor to y.__proto__.constructor. I also like how Object.prototype sits at the top of the prototypical inheritance chain with Object.prototype.__proto__ set to null. I also like how the diagram makes a three column conceptual visualization of how the programmer thinks of objects as 1. instances, 2. constructors, 3. prototypes which constructors associate with those instances when instantiated via the new keyword.
    • mlvljr
      mlvljr over 9 years
      Diagram makes immediate sense after you watch something like youtube.com/watch?v=_JJgSbuj5VI , btw
    • mlvljr
      mlvljr over 9 years
      And now, as I've read through the answers, feel obliged to really recommend the above video, as it indeed has a crystal clean (and non-WTFy) explanation of what's going on :)
  • rvighne
    rvighne almost 10 years
    Ah! So prototype is not available on the instances themselves (or other objects), but only on the constructor functions.
  • kzh
    kzh almost 10 years
    Also if you change the __proto__ property of an object, it changes the object on which prototype lookups are done. For instance, you can add an object of methods as a function's __proto__ to have a sort of callable instance object.
  • demisx
    demisx almost 10 years
    There are more to __proto__ and prototype, than just the naming convention. They may or may not point to the same object. See @zyklus answer.
  • Tarik
    Tarik over 9 years
    @rvighne: prototype is only available on functions since they are derived from Function, Function, and Object but in anything else it is not. However, __proto__ is available everywhere.
  • 成 周
    成 周 over 9 years
    @demisx of course you said is right, but my opinion is name difference exposed the contrast of the functionality.
  • yoel halb
    yoel halb over 9 years
    I upvoted it, but maybe the downvote reason was because the statement "prototype is used by constructor() functions" might sound as if non constructor functions does not have, which is not the case, however besides that it is not our focus now also one can note that every function is potentially a constructor if called with new...
  • Alex_Nabu
    Alex_Nabu almost 9 years
    So __proto__ is the actual object that is saved and used as the prototype while Myconstructure.prototype is just a blueprint for __proto__ which, is infact the actual object saved and used as the protoype. Hence myobject.prototype wouldnt be a property of the actual object because its just a temporary thing used by the constructor function to outline what myobject.__proto__ should look like.
  • Alex_Nabu
    Alex_Nabu almost 9 years
    Probably one of those things build into the language when it was trying to imitate classical oop. If it wasn't we would perhaps instead have seen something more along the lines of var mycar = Object.Createfrom(car.__proto__); when creating objects. More true to a prototypical style of programming.
  • Alexander Gonchiy
    Alexander Gonchiy almost 9 years
    Please change "constructor() functions" to "constructor functions", since there might be confusion with "__proto__.constructor() functions". I consider this important, as __proto__.constructor isn't actually invoked when a new keyword is used.
  • ProfNandaa
    ProfNandaa almost 9 years
    It's not just enough to state "as per your understanding", especially when other good answers have been provided before...
  • Niko Bellic
    Niko Bellic almost 9 years
    Is it fair to say that the __proto__ property of an object is a pointer to the object's constructor function's prototype property? i.e. foo.__proto__ === foo.constructor.prototype
  • epeleg
    epeleg over 8 years
    Only that I would write it the other way around: foo.__proto__ === foo.constructor.prototype
  • seangwright
    seangwright over 8 years
    @Alex_Nabu Not quite. newCar.__proto__ IS Car.prototype, not an instance of Car.prototype. While Car.protoype IS an instance of an object. Car.prototype is not something that gives newCar any properties or structure, it simply IS the next object in newCar's prototype chain. Car.prototype is not a temporary object. It is the object that is set as the value of the __proto__ property of any new objects made using Car as a constructor. If you want to think of anything as a blueprint object, think of Car as a blueprint for new car-objects.
  • Francisco
    Francisco about 8 years
    myPoint.__proto__.constructor.prototype == Point.prototype
  • Mikhail Batcer
    Mikhail Batcer about 8 years
    Why can't I change, for example, __proto__ of a string to an array instance: s = "foo"; a = []; s.__proto__ = a; ?
  • None
    None about 8 years
    @MikhailBatcer -- Primitives in JS are a special case. Whenever you access them they're effectively converted into an instance of the appropriate class type and then the ops are run on that. So after the code you wrote, s.__proto__ is something close to (new String(s)).__proto__. If you replaced your first statement with s = new String('foo'), it'd work. It's just this weird quirk in JS
  • Yiling
    Yiling about 8 years
    The statement that "prototype is used by constructor() functions" tells only part of an important fact but told it in a way that likely lead readers to think it is the whole fact. prototype is internally created for upon every function declaration in Javascript, regardless of how that function will be called in the future - with or without the new keyword; prototype of a declared function points to an object literal.
  • abhisekp
    abhisekp almost 8 years
    I was wondering why was the prototype object created internally in the first place? Could one simply assign static methods to the function object itself. e.g. function f(a){this.a = a}; f.increment = function(){return ++this.a}? Why wasn't this way chosen over adding the methods to prototype object? This will work if f.__proto__ = g where g is the base class.
  • abhisekp
    abhisekp almost 8 years
    Maybe prototype object was choosen for sharing because only the exclusive function constructor properties can be stored in function constructor object.
  • abhisekp
    abhisekp almost 8 years
    @kzh lol that gave me funny result console.log(obj1.call) // [Function: call] obj1.call() // TypeError: obj1.call is not a function. I did obj.__proto__ = Function.__proto__
  • abhisekp
    abhisekp almost 8 years
    Actually, that would be a mess because instanceof would result in ({}) instanceof Function === true as there would be no way to differentiate between prototypes if the prototype property is removed.
  • kzh
    kzh almost 8 years
    myFn.__proto__ = {foo: 'bar'}
  • Daniel
    Daniel over 7 years
    @Niko Bellic Gotcha! It's fair to say that proto property of an object is a pointer to the object's constructor function's prototype property, but that's not fully right (at least if you replace the prototype of a non native constructor by a primitive value literal i.e: '' || 0 || true afaik)! I tested this on Chrome and it returned something different: function MyConstructor () {} MyConstructor.prototype = ''; (new MyConstructor).__proto__ !== MyConstructor.prototype. I think the browser fails to create proto with a primitive literal, creating it with Object.prototype
  • Daniel
    Daniel over 7 years
    @Niko Bellic Actually it doesn't create it with Object.prototype either, I may need to look at this for a little long, to give a more precise answer! However (new MyConstructor).__proto__ is actually the same as (new MyConstructor).constructor.prototype!
  • None
    None over 7 years
    @Daniel - There are so many ways to break JavaScript, but honestly I don't see the point in discussing edge cases that no sane person would ever hit! :)
  • Christof Kälin
    Christof Kälin over 7 years
    Nope, neither prototype nor a __proto__ are used on any time as a blueprint or so to create any object. This is a myth introduced by the blurry class syntax and it's predecessors. As the answer-post says it's just used for the lookup-chain and in case of prototype to identify constructor used with new (which is part of that pretend-to-be-classy mechanism that is confusing many users including me).
  • doubleOrt
    doubleOrt over 6 years
    @abhisekp What do you mean by this: "This will work if f.__proto__ = g where g is the base class." I don't know if this has some meaning i don't understand, but if you were to add the properties and methods in that way, then when you used the new keyword to create an instance, the properties and methods wouldn't be copied over.
  • doubleOrt
    doubleOrt over 6 years
    1. constructor does not return a()! It returns a. 2. __proto__ returns Object.prototype, not the root object in Javascript.
  • doubleOrt
    doubleOrt over 6 years
    Object.prototype is not a property of an object literal, trying to print out {}.prototype returns undefined; however, it can be accessed via {}.__proto__, which returns Object.prototype.
  • Lior Elrom
    Lior Elrom over 6 years
    @Taurus, click on the header, it leads to the ECMAScript specifications doc. Check out section 9 (Ordinary and Exotic Objects Behaviours) which explain it in much more details.
  • doubleOrt
    doubleOrt over 6 years
    prototype is not used to create the __proto__ of an object. __proto__, when accessed, merely provides a reference to the prototype object.
  • Andreas
    Andreas about 6 years
    That's exactly why an answer to "__proto__ VS. prototype in JavaScript" ?
  • Dmytro
    Dmytro about 6 years
    still thinking of more coherent names for __proto__ and prototype. maybe prototype and inheritance?
  • HASSAN MD TAREQ
    HASSAN MD TAREQ about 6 years
    I would say, prototype & __proto__ both should be avoided. We have class now and I like OOP.
  • Dmytro
    Dmytro about 6 years
    the problem is that class is relatively new and it isn't supported by really convenient engines like microsoft JScript(nice to have when working on C and need a quick and dirty script engine that's always there), and nashorn javascript(which comes with all new Java installations under jjs and is a nice way of putting Java into a pure dynamic environment where you don't need to constantly recompile things). The thing is if class was sugar, it wouldn't be a problem, but it isn't, it offers things that are impossible without them in older js versions. Like extending "Function".
  • HASSAN MD TAREQ
    HASSAN MD TAREQ about 6 years
    Eventually we will get support. I am backend developer, so I don't have issues, I code in js rarely.
  • Dmytro
    Dmytro about 6 years
    and inheriting static members in a way that adding new/removing static members from parent is noticed by child(which I can't think of a way to do on JScript, which doesn't offer Object.assign/__proto__/getPrototypeOf, so you have to tinker with the root Object.prototype to simulate it)
  • Jyoti Duhan
    Jyoti Duhan almost 6 years
    @Derick Daniel: not sure why you down voted this but the edit you made was not that I was trying to convey. Edited it further for more clearance :).
  • Derick Daniel
    Derick Daniel almost 6 years
    Jyoti, i did not down vote your answer, someone else did, i just edited it :)
  • Nitin Jadhav
    Nitin Jadhav over 5 years
    The first point should be "I'm a function and I build new objects that will delegate to my prototype"
  • Shaz
    Shaz over 5 years
    Just to be clear: instances do no have .prototype property? Only the constructor function right? ... So a difference between an instance and its constructor function is: constructor functions have both 1. proto 2. .prototype object while the instances only have .__proto__ property... correct?
  • AL-zami
    AL-zami over 5 years
    @Shaz you are right. instances uses their proto to access the prototype property of their constructor function.
  • Shaz
    Shaz over 5 years
    But why why is it when you write: var car = Object.create(Vehicle); you will get car.__proto__ = Vehicle BUT you also get a car.prototype property that points to Vehicle.prototype ?
  • AL-zami
    AL-zami over 5 years
    @shaz can you provide a jsfiddle so that i can visualize the situation?
  • Shaz
    Shaz over 5 years
    jsfiddle.net/shahyan3/b5tr3zhk/6 Here it is... check out the car and car2 as examples. Any ideas?
  • AL-zami
    AL-zami over 5 years
    here car.prototype is an inherited property. car inherits 'prototype' property from vehicle function. so car.prototype === vehicle.prototype. " prototype" property is a property on vehicle. car can access it through its prototype chain. I hope this will clear your confusion
  • Shaz
    Shaz over 5 years
    OH I see. New to JavaScript world, your answer is so good. Quickly, is it a common practice to write: Object.create(Vehicle) OR Object.create(Vehicle.prototype)... I am guessing the latter is more popular use case - in your experience?
  • john-raymon
    john-raymon almost 5 years
    This is a great answer!
  • Selva Ganapathi
    Selva Ganapathi almost 5 years
    is it good or what about Foo.collection.push(this) Foo.count++
  • ComicScrip
    ComicScrip over 4 years
    I think I've got your Point.
  • Geocrafter
    Geocrafter over 4 years
    Very well explained!
  • ezio4df
    ezio4df over 4 years
    @theshinylight, tom.__proto__ and Cat.prototype are stricly equal, So, tom.__proto__ === Cat.prototype And Cat.prototype === tom.__proto__ are true. So, what did you mean by the arrow in the image ??
  • theshinylight
    theshinylight over 4 years
    The black arrow (if you are referring to it) has no particular meaning, other than the property of the object. So prototype is property of the Cat object (from your question).
  • java-addict301
    java-addict301 about 4 years
    +1 this is the best answer for explaining what prototype actually IS (an object with two properties) and how Javascript executes each piece of code. This info is surprisingly hard to come by.
  • seeker
    seeker almost 4 years
    Brilliant explanation
  • Sébastien
    Sébastien over 3 years
    Constructor functions and classes also have a __proto__ property, it's not reserved for instances. Constructor functions and classes have a __proto__ property and also a prototype property. See stackoverflow.com/a/42002749/1347953
  • Vigneshwaran Chandrasekaran
    Vigneshwaran Chandrasekaran almost 3 years
    Short and sweet
  • Alvaro Prieto
    Alvaro Prieto over 2 years
    Thank you, I ve read a lot of post... and yours is the most convincing one. It is hard to digest in the beginning, but then everything has sense.