Internal [[Prototype]] and external prototype

For brevity, I will not outline the details of the instanceof operator (you can always check the ECMAScript specification), but at a high level, it simply tests whether an object has in its prototype chain the prototype property of a constructor. But testing the prototype chain does not mean looking up the external prototype property which everyone is familiar with— it refers to the internal [[Prototype]] property:

All objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance.

Being an internal property, [[Prototype]] is not directly accessible, however, it can be interacted with using Object.getPrototypeOf. This internal property is present for all objects, handling property and method lookups.

In contrast, the external prototype property is specific to Function objects:

The value of the prototype property is used to initialize the [[Prototype]] internal property of a newly created object before the Function object is invoked as a constructor for that newly created object.

This means that the prototype is the object that is used to build [[Prototype]] when you create an object using the new keyword. In other words, when a function object is used as a constructor, a new object will be created and the new object will have its [[Prototype]] initialized with its prototype property.

Take the following example:

// Function object that will be used as a constructor

function Car(){} // Car.prototype has a single property called "constructor"

// which points back to Car

Car.prototype.constructor === Car // true // Car.prototype is an object

// console.log(Car.prototype) => Object {}

Car.prototype instanceof Object // true // Create an object using the new keyword

var myCar = new Car() // The internal [[Prototype]] of `myCar` is initialized

// with `Car.prototype`

Object.getPrototypeOf(myCar) === Car.prototype // true

With the above snippet we can state the following points:

Car . prototype points to an automatically created new object. This is what JavaScript does by default when you declare a function.

. points to an automatically created new object. This is what JavaScript does by default when you declare a function. Car.prototype is empty except for a constructor property which points back to the constructor function itself

is empty except for a constructor property which points back to the constructor function itself Car.prototype is an instance of an object.

is an instance of an object. myCar ’s [[Prototype]] is Car.prototype.

’s is The next object in myCar’s prototype (i.e, [[Prototype]]) chain is Car.prototype.

The last line (Object.getPrototypeOf(myCar) === Car.prototype) demonstrates that myCar is indeed an instance of Car. We can verify this programmatically:

myCar instanceof Car // true

We can see here how the instanceOf operator keeps walking up at the prototype chain to determine whether the left hand side’s [[Prototype]] is equal to the right hand side’s prototype.