Prototypes: The Short(est Possible) Story
What is a prototype?
The steps for property lookup (e.g.
me.name) are very simple:
1) Look in
me for the property. If found, return the value of that property. else, step 2.
2) Look in
me’s [[Prototype]] object for the property. If found, return the value of that property.
person is an object”, I hear you cry, “what if it has a [[Prototype]]?”. Fear not! you simply repeat the steps above for finding a property in
person. Consider this:
me.is_alive // => true may be a little baffling, but it’s really rather simple when you think it through:
1) look for property ‘is_alive’ on
2) it hasn’t been found, so look on
3) it hasn’t been found, so look on
4) it has been found, so return the value
N.B. This is just a mental model for thinking about how the lookup works; the actual implementation may vary
This ‘chaining together’ of prototypes is known (unsurprisingly) as the
prototype chain. Think about it! This means you can add a property at any time to
animal and that will be available on
me for all to see.
How to use them!
Up till now we’ve been pretending that
person is the [[Prototype]] of
me, but it’s all been a lie. Let’s resolve that:
This is the older syntax; and is the cause of a lot of the confusion about prototypal inheritance.
Constructors are functions that, when called in conjunction with the
new keyword, return a fresh object. If you want to use a function as a constructor, the convention is to use a capital first letter:
So, now we have a
person object, how do we make sure that it is the [[Prototype]] of
me? Like so:
When you call
Me with the
new keyword, the fresh object (represented by
this inside of the constructor function) has its [[Prototype]] set to Me.prototype. After that, the body of the
Me function is run, and the object represented by
this is returned. Phew. What a load of confusion that causes.
Why did I leave out
animal in these examples? Well, because this technique requires a lot of boilerplate, and I didn’t want to make it any more confusing than necessary.
* As kangax’ compatibility tables show us, ie8 and lower, ff 3.6 and lower, and even Opera 11.50 lacks support for Object.create.