console.log('-----------------------------Object'); var obj = {}; console.log(obj.__proto__ === Object.prototype); // true console.log(Object.prototype); // Object console.log(obj.prototype); // undefined console.log('-----------------------------Function'); // prototype is a Object property of a Function var func = function () {}; console.log(func.__proto__ === Function.prototype); // true console.log(func.prototype === Function.prototype); // false console.log(func.prototype === Object.prototype); // false console.log(func.__proto__.__proto__ === Object.prototype); // true console.log(func.prototype.__proto__ === Object.prototype); // true console.log('-----------------------------new func'); // we look for say from this, then from __proto__ up func.say = function () { console.log('func say'); } func.__proto__.say = function () { console.log('func proto say'); } func.prototype.say = function () { console.log('func prototype say'); } // From this, we know that __proto__ is only used as pointer to find parent proto. // And what the newed object has is determined by its prototype, and prototype.__proto__ etc. //func.prototype.__proto__ = func.__proto__; var new_func = new func(); new_func.say(); func.say(); // var new_func = {}; // new_func.__proto__ = func.prototype; // func.call(new_func); console.log(new_func.__proto__ === func.prototype); // true console.log(new_func.prototype); // undefined, as it's an Object func.prototype.say = function () { console.log('func prototype say 2'); } new_func.say(); // say 2 console.log('-----------------------------derived'); var de_func = function () { }; de_func.prototype.__proto__ = func.prototype; var new_de = new de_func(); new_de.say(); // remember: // 1. var x = new obj(); means x.__proto__ = obj.prototype // 2. we look for member from this first, then from this.__proto__