Prototypal Master Class, Introduction

© 2011, Martin Rinehart

This is the introduction to a series of pages showing how master JavaScript programmers have handled prototypes in their JavaScript code. Elsewhere I have been critical of "experts" who have written on this subject—written a great deal of misinformation. I've advised you to look for working code. Talking the talk is cheap. Walking the walk takes real understanding. This series is about code that walks the walk.

Before we begin, a brief review is in order.

The Prototype

The basic concept of prototypal inheritance is simple: each object has a prototype object. Properties not found in the object itself will be taken from the prototype object. Reminder: JavaScript properties can be any JavaScript values including primitives (such as booleans, numbers and strings) and objects. Objects include arrays, functions and other objects. Properties include both data and methods, as a method is simply a property that is a function.

The prototype of an object is, itself, an object. The previous paragraph applies recursively. If a property is not found in the prototype, then the prototype's prototype is searched for the desired property. This search continues until it comes to the original Object.prototype.

Objects that are part of the DOM may not have prototypes. Don't use them as part of the prototype chain.

The Implicit Reference

In JavaScript, objects do not explicitly refer to their prototypes. Instead, they have implicit references to their prototypes. JavaScript follows these references when it searches the prototype chain. You cannot read or write these implicit references, unfortunately.

Initially, an object created by a constructor (which includes object literals that are created by the Object constructor) refer to the property of the constructor named prototype. If you want to assign a specific object as a prototype you can assign that object to the constructor's prototype property: Constructor.prototype = specific_object;. This implies that while you have no direct control over the object's implicit prototype reference, you have complete control over the actual object found by that reference.

The Default and Custom Prototypes

When a function is created, it is given a property named prototype and that property's value is an empty object. It is as if the Function constructor did this:

function Function() {
    this.prototype = {};
    /* other code */

The Function prototype type is written in "native code" (probably C++), not JavaScript, which may be good for efficiency but it is not helpful if you want to customize it. The assignment of a custom prototype object is, however, a simple matter:

function My_constructor( params ) {
    /* your code here */
My_constructor.prototype = my_object;

For example:

function Foo() {}
Foo.prototype = { x: 2 };

alert( new Foo().x ); // 2

Moving On

With that short review, you have everything you need to know to understand the code of these four different approaches to prototypal JavaScript. (These are roughly in order of least to most complex.)

Feedback: MartinRinehart at gmail dot com

# # #