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:

var a = {};

The following do not work, because only a function has the prototype property:

({}).prototype // undefined
a.prototype // undefined

The true prototype of an object is held by an internal property, which can be accessed in the following ways:

Object.getPrototypeOf(a); // ECMA 5
a.__proto__; // all browsers except IE

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.

a.constructor.prototype;

When a primitive is asked for it’s prototype it will be coerced to an object.

false.__proto__ === Boolean(false).__proto__; // true

Using prototype for inheritance (note Array is the array constructor):

a.__proto__ = Array.prototype;
a.length; // 0, because a "is" now an Array

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.

var A = function() {};
var a = new A(); // using A as a's constructor
a.__proto__ === A.prototype; // true
A.prototype.constructor == A; // true
a.constructor == A; // true

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:

(new Function()).prototype;

Math is not a function so no prototype property:

Math.prototype; // undefined

A function (object)’s prototype is not the same as it’s prototype property

A.__proto__ != A.prototype; // true

A’s prototype is set to its constructor’s prototype property (Function is the constructor for all function objects):

A.__proto__ == Function.prototype; // true

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.

a.__proto__ === A.prototype; // true
a instanceof A; // true
a.__proto__ != Function.prototype; // true
a instanceof Function; // false

Mess around with a’s prototype, so that a’s prototype no longer in same prototype chain as A’s prototype property:

a.__proto__ = Function.prototype;
a instanceof Function; // true
a instanceof A; // false

Function augmentation

String.prototype.times = function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
}

"hello world!".times(2); // "hello world!hello world!"