Understanding JavaScript Prototype
- Object and function
- Object prototype
- Function prototype property
- Prototype chain and prototypical inheritance
- Function augmentation
This shall be a 10-minute read on the JavaScript prototype topic. It is my notes when reading Angus Croll’s post on the same topic. All the code examples here can be easily verified using nodejs or browser developer tools, e.g., that of Chrome. Feel free to let me know if there is anything mistaken.
Object and function
An object in JavaScript is an unordered collection of key-value pairs. If it’s not a primitive (undefined, null, boolean, number or string), it’s an object. A function is also an object.
Note in the following the difference between term prototype and the term prototype property. The former is used in an object context, whereas the latter in a function context.
Object prototype
Create an object:
The following do not work, because only a function has the prototype property:
The true prototype of an object is held by an internal property, which can be accessed in the following ways:
Most of the time, an object’s prototype is the prototype property of its constructor (which is a function). The following works on all browsers, but only if constructor.prototype has not been replaced.
When a primitive is asked for it’s prototype it will be coerced to an object.
Using prototype for inheritance (note Array is the array constructor):
Function prototype property
A function’s prototype property is the object that will be assigned as the prototype to all instances created using this function as a constructor. That object is the prototype for all those instances.
Every function gets a prototype property (built-in function excepted), i.e., it
can be accessed using the .prototype
syntax. Anything that is not a function
does not have such a property.
Note the above a
’s constructor property is inherited from it’s prototype.
More on that in the next section.
This function will never be a constructor but it also has a prototype property:
Math is not a function so no prototype property:
A function (object)’s prototype is not the same as it’s prototype property
A’s prototype is set to its constructor’s prototype property (Function is the constructor for all function objects):
Prototype chain and prototypical inheritance
When object a
is asked to evaluate property foo
, JavaScript walks the
prototype chain (starting with object a itself), checking each link in the
chain for the presence of property foo. If and when foo is found, it is
returned, otherwise, undefined
is returned.
Prototypical inheritance is not a player when property values are set. a.foo =
'bar'
will always be assigned directly to the foo
property of a
.
The expression a instanceof A
will return true if A
’s prototype property occurs in a
’s prototype chain.
Mess around with a’s prototype, so that a
’s prototype no longer in same prototype chain as A’s prototype property: