The __proto__ and prototype are two key properties in Javascript. Its little bit hard to grasp at first. But just remember some simple rules, you will be able to get it very quick.

Each object has __proto__ property

Including function and instance. Because function is also an object.

 
function foo () {}
 
foo.__proto__ == Function.prototype
 
true
 
window.__proto__ = Window.prototype
true
 
var obj = new f () ;
obj.__proto__ == f.prototype
true
 

__proto__ always reference to constructor's prototype of the object

In the example above, f is the constructor of obj. So obj.__proto__ == f.prototype.

The trick part is the function object, a function object is an object constructed by another function, and itself can be a constructor when it used to create new object.

Every function in Javascript, include Function itself, Object(), and other normal functions is constructed by Function ().

So.

 
foo.__proto__ == Function.prototype
Function.__proto__ == Function.prototype
Object.__proto__== Function.prototype
 
 

Only function object has prototype property

Any function can be a constructor , a constructor must has a prototype object. When the function is used to construct object, the object's __proto__ will reference to the constructor's prototype object.

 
obj.prototype == undefined
true
window.prototype == undefined
true
 

prototype has __proto__

The first rule claim that each object has __proto__, it also apply on prototype object.

The constructor of prototype object is Object(). So initially every prototype object's __proto__ reference to Object.prototype.

But we can change it by a little trick.

Object.prototype.__proto__ == null

This is the end of prototype chain which introduced in next section.

prototype chain

When you reference any property of any object, Javascript execute a search process.

First step, look at its own properties. If no exist, looking for __proto__ property.

Second step, since __proto__ reference to some function's prototype object, it try to find property in the prototype object. If not found, keep try on the __proto__ property of the prototype, until the __proto__ is null.

Construct prototype object

Each function has a prototype object when its created, its added automatically by system.

But prototype object is just a normal object, we can construct it by hand.

Suppose we have two function child, parent, we will construct a prototype object for child . The instance created by child will be able to access prototype property of parent.

 
function extend( child, parent ) {
    var parentPrototype = parent.prototype, foo = function() {};
    foo.prototype = parentPrototype;
    var obj = new foo();
    child.prototype = obj;
    obj.constructor = child;
}
 
var p = function () { console.log("parent") }
var c = function () { console.log("child") }
 
extend( c, p ) ;
 
p.prototype.Hello = function () { console.log("Hello") }
var instance = new c ();
instance.Hello();