Suppose you're designing an API for all functions. So you define that every function should have the method call. You create an object with such method:
var fproto = {call: ()=>{}};
Then for all functions to share this functionality, you have to add it to .prototype property of a Function constructor, so that all instances of a Function inherit it. So you do the following:
Function.prototype = fproto.
Now, when you create a function F, it will have have its .__proto__ set to fproto:
const F = new Function();
F.call(); // works because of lookup in prototype chain through `__proto__` property
F.__proto__ === Function.prototype; // true
Now you decide that all instances created using F constructor, should have a method custom, so you create an object iproto with the property and set it as a prototype for all instances of F using prototype property:
const iproto = {custom: ()=>{}};
F.prototype = iproto;
const myobj = new F();
myobj.custom(); // works
So now it should be clear that F.__proto__ and F.prototype are not the same object. And this is essentially what happens under the hood when you declare a function:
const F = function() {};
// F.__proto__ is set to Function.prototype to inherit `call` and other methods
F.__proto__ === Function.prototype
// F.prototype is set to a new object `{constructor: F}` and so:
F.prototype !== Function.prototype
Function.prototype === Function.__proto__
Is an exceptional case because Function constructor should have all methods available for function instances, and hence Function.__proto__, but all share these methods with function instances, hence Function.prototype.
Suppose you're designing an API for all functions. So you define that every function should have the method
call. You create an object with such method:Then for all functions to share this functionality, you have to add it to
.prototypeproperty of a Function constructor, so that all instances of a Function inherit it. So you do the following:Now, when you create a function
F, it will have have its.__proto__set tofproto:Now you decide that all instances created using
Fconstructor, should have a methodcustom, so you create an objectiprotowith the property and set it as a prototype for all instances ofFusingprototypeproperty:So now it should be clear that
F.__proto__andF.prototypeare not the same object. And this is essentially what happens under the hood when you declare a function:Is an exceptional case because
Functionconstructor should have all methods available for function instances, and henceFunction.__proto__, but all share these methods with function instances, henceFunction.prototype.