Why does Function have both implicit and explicit prototype references, and can I set the implicit reference?

function, javascript, prototypal-inheritance, prototype

Solution

Consider the diagram from the specification, and the code below it, which tries to reproduce what's going on:

function CF() {};            // the constructor
CF.P1 = 'foo';               // P1 is an own property of the constructor; P2 is the same
var CFp = { CRP1: 'bar' };   // for now, just an object, with a CRP1 property
CF.prototype = CFp           // set CFp as the 'explicit prototype property' of CF;
                             // only constructors have such a property
var cf1 = new CF();          // an instance; 
var cf2 = new CF();          // another instance; cf3..cf5 are constructed the same way
Object.getPrototypeOf(cf1);  // CFp; this is the 'implicit prototype link' from cf1 to CFp;
                             // put another way, CFp became the [[Prototype]] of cf1

You said you were confused by this sentence: the property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF). Consider this:

cf1.CRP1;   // 'bar' - found on CFp through cf1
cf2.CRP1;   // 'bar' - found on CFp through cf2
CF.CRP1;    // undefined

So what that sentence means that you can access the contents of `CRP1` from `cf1..cf5`, but not from the constructor `CF` (remember, functions/constructors are objects too, thus they can have properties). And that's because `CFp` (the "owner" of `CRP1`) is not the `[[Prototype]]` of `CF`, it's just the value pointed by the `CF.prototype` property. The `prototype` property only exist in function objects, and is used solely to define the `[[Prototype]]` of instances created by invocations of the function is invoked as a constructor (like in `new CF()`). The fact that both `[[Prototype]]` and `prototype` read as "prototype" is the source of great confusion – and maybe part of what is confusing you; hopefully, it's less confusing now. With that in mind, I'll try to shortly answer your other questions.

Much of the literature on Javascript points out that functions are first class objects, and as such I'd expect to be able to set their implicit prototype reference like an object to achieve prototypal inheritance [...].

In ES5 there is no way to directly set the implicit prototype reference (or `[[Prototype]]`) of an existing object, except for the non-standard `__proto__` property. What you can do is create new objects with a given `[[Prototype]]`. You can do that with `var obj = new ConstructorFunction()`, where the `[[Prototype]]` of `obj` is `ConstructorFunction.prototype`, or with `var obj = Object.create(someOtherObj)`, where the `[[Prototype]]` of `obj` is `someOtherObj`. The later versions of the language introduced `Object.setPrototypeOf` to do that, but its use is discouraged for performance reasons.

Can I set this implicit prototype on a function, or will it always point to Function.prototype (I'm assuming that's the default).

Yes, with `__proto__` or `Object.setPrototypeOf`. But usually you shouldn't.

And why does Function have both explicit and implicit prototypes? Also do any other types in Javascript have both explicit and implicit prototype references or is Function unique in this regard?

`Function` ("the `Function` constructor") is just a function, and as any other function it has a `prototype` property; it's also an object, and as (almost) any other object is has a `[[Prototype]]` object. There are standard constructors for other types too, like `Object`, `String`, `Array`, `Boolean`, `Number`. They're all functions, and have both a `prototype` and a `[[Prototype]]`.

Problem

After reading this documentation: http://es5.github.io/#x4.2.1 I was confused by the two prototype references on CF, and by this statement: The property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF) Much of the literature on Javascript points out that functions are first class objects, and as such I'd expect to be able to set their implicit prototype reference like an object to achieve prototypal inheritance (disclaimer: I don't actually know what I'd use this inheritance for, but it occurred to me to see if it's possible). Can I set this implicit prototype on a function, or will it always point to Function.prototype (I'm assuming that's the default). And why does Function have both explicit and implicit prototypes? Also do any other types in Javascript have both explicit and implicit prototype references or is Function unique in this regard?

Original source