There are actually two different kind of "prototype" in JavaScript:
- One is the "hidden" link every object has (let's use
[[Prototype]]
to represent this hidden link). object literals by default have their hidden links pointing to Object.prototype
, function objects have their hidden link pointing to Function.prototype
, and arrays have theirs pointing to Array.prototype
. These hidden prototype links are not related to properties with name "prototype". You can't change these hidden links by adding or modifying o.prototype
.
- Another one is that all function objects automatically have a special property named "
prototype
". This is mainly for the usage of constructor invocation pattern.
[[Prototype]]
is used for searching properties (like the parent in classical hierarchy), whenever a property cannot be found in an object, its [[Prototype]]
is searched instead. One usage scenario: say you'd like to add a property to all objects, you could simply add it to Object.prototype
which would automatically apply to all objects since all objects somehow have Object.prototype
as their [[Prototype]]
chain root.
Lets get back to function objects' "prototype
" property. It is only useful when used with operator new
. Take the following code snippet as an example:
function F() {} // function declaration
// F now has a property named "prototype"
var f = new F(); // use "new" operator to create a new function object based on F
What new F()
does above is to first create a new function object, set the [[Prototype]]
(hidden link) of this newly created function object to be F.prototype
, and then return the new function object. This is probably what you already understand that works for function objects.
Remember that I said we can't change objects's [[Prototype]]
? Well, at least not directly. Crockford's Object.create
function does just that, by utilizing the fact that operator new
could help set [[Prototype]]
for us. So by using Object.create
, you get to deliberately indicate where your new object's hidden link should point to. (somewhat feel like indicating who is your parent class)
In your example, conf
is an object literal and conf.prototype
isn't really useful. Here's another version utilizing classical style:
function ConfBase() {}
ConfBase.prototype.d = 16;
var conf = new ConfBase();
conf.a = 2;
conf.b = 4;
document.writeln(conf.a);
document.writeln(conf.b);
document.writeln(conf.d);
Compared to the answer of @CMS, I do prefer using Object.create
. But essentially the 2 styles are using the same underlying mechanism, just that Object.create
helps tidy it up.