Nikita Vlasenko
Nikita Vlasenko

Reputation: 4352

Why constructor function prototype can be assigned to an object and what it means

I am reading through the official docs:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

and in the chapter Different ways to create objects and the resulting prototype chain -> With a constructor they have the following:

function Graph() {
  this.vertices = [];
  this.edges = [];
}

Graph.prototype = {
  addVertex: function(v) {
    this.vertices.push(v);
  }
};

var g = new Graph();
// g is an object with own properties 'vertices' and 'edges'.
// g.[[Prototype]] is the value of Graph.prototype when new Graph() is executed.

But right before that it is written that:

// Functions inherit from Function.prototype 
// (which has methods call, bind, etc.)
// f ---> Function.prototype ---> Object.prototype ---> null

So, Graph is a function and it should have Graph.prototype, in my understanding, to be of type Function.prototype and NOT Object.prototype, otherwise Graph would stop being a function and would instead become an object, or so I would think.

Could anyone explain why the prototype of Graph is assigned to an object and why the specified behavior of inheriting then addVertex becomes possible? Would we lose all of the function properties (call, bind) when such assignment happens?

Upvotes: 1

Views: 48

Answers (1)

trincot
trincot

Reputation: 350137

There are two different prototype chains at play:

  1. The prototype chain of the constructor
  2. The prototype chain of objects that are created by that constructor

They have nothing to do with each other. The first is a function and thus related to Function.prototype, the other is not a function, but an object whose prototype object is created at the same time as the constructor function object was created. That prototype object will be used when a new instance is created by calling the constructor with new.

What can be confusing here, is that the constructor has a property that is called prototype, but that is not the prototype object of the constructor (point 1), but of objects it can create (point 2). Possibly this property would have been better named prototypeForConstructedInstances... but that's a bit long ;-)

To get the constructors own prototype you would write Object.getPrototypeOf(constructor),... and you'll see it is Function.prototype.

You may have an interest in reading more about the broader subject of prototypes at "How does JavaScript .prototype work?". It's an interesting read, and you'll also find my answer over there.

Upvotes: 2

Related Questions