JavaScript Prototypal Inheritance

© Andrea Giammarchi - 23 March 2008

Summary

JavaScript is the world's most misunderstood programming language, and even if we use them from about 10 years, there is still confusion about the basis of its prototypal inheritance nature. This page aim is to clarify this aspect of this wonderful scripting language that a lot of developers still do not perfectly understand. I hope this page will be useful even if I know my English is not good as my JavaScript knowledge is (so, sorry for language typos).

top menu

Object

Quite everything, in JavaScript, inherits from Object. We could say that Object is the super class, or better, the super constructor, of every variable and that everything is an instanceof Object. The Object constructor is a Function, but a Function is an instanceof Object. This means that these assertions are always true:

(Object instanceof Function) === (Function instanceof Object)
            

Above example is true because Object is a constructor, and a constructor in JavaScript is always a Function. At the same time, every Function has its own prototype, and a prototype always starts its inheritance from Object.prototype. The Function constructor, is a Function itself, and the function prototype is a function(){};

(Function.prototype instanceof Object) === (function(){} instanceof Object)
            

These case describes the begin of prototypal hierarchy. These are particular cases that could probably cause only confusion. The reason I wrote about these cases, is to make this paper more complete than others, but everything we really have to remember, is that Object.prototype is the real root of JavaScript inheritance.

Note 1: this assertion is an ambiguous exception, and it is probably the only one in the root of inheritance:

!(Object.prototype instanceof Object) === (Object.prototype.constructor === Object)
            

Note 2: when I wrote that quite every variable inherits from Object.prototype, I mean that it depends of engine. For some reason, some browser (Internet Explorer) does not follow this basic rule. This means that if we change Object.prototype, some variable could not inherits that method or that property. DOM elements, and DOM interactions, are probably the best example of these engines limit, and another valid reason to do not extend the Object.prototype as well (please read more to know why).

top menu

prototype basis

As prototypal inheritance based language, we do not necessary need classical inheritance to extend or add features for every instance/variable. In fact, if we add or modify a method or property from Object.prototype, every variable will inherit automatically them.

// declare a primitive Number variable
var num = 255;

// num inherits from Number.prototype first and Object.prototype after

// add a method to Object.prototype
Object.prototype.toHEX = function(){
    return  "0x" + this.toString(16);
};

// num has automatically inherited that method
num.toHEX(); // 0xff
            

Above example is as valid as illogical. The main reason it is valid is that num, that is a Number, where Number.prototype inherits from Object.prototype, can use toHEX method returning expected result. On the other hand, toHEX method is dedicated for Number instances and not for generic objects. That is why that method could be assigned to Number.prototype.

// declare a primitive Number and String variable
var num = 255,
    str = "15";

// toHEX for generic objects
Object.prototype.toHEX = function(){
    return  parseInt(this, 10).toHEX();
};

// toHEX for Numbers
Number.prototype.toHEX = function(){
    return  "0x" + this.toString(16);
};

// num uses Number.prototype.toHEX
num.toHEX(); // 0xff

// str uses Object.prototype.toHEX
str.toHEX() // 0xf;
            

Every variable will inherit toHEX method from Object.prototype, while every instanceof Number will inherit its dedicated toHEX method. Above example shows an override in inheritance chain performed during Number.prototype.toHEX declartion. While numbers will use directly the correct toHEX method, booleans, strings, dates, others, will use Object.prototype.toHEX one to convert theirself into a base 10 integer number and use then Number.prototype.toHEX to obtain the result. As summary, every instanceof Number will search for its constructor prototype methods, the Number, and if it will not exist, instances will search into Object prototype. This is the basis of prototypal inheritance, we could just start creating common methods to use with native constructors or Object.prototype ... or not?

Object.prototype ... forbidden?!

Even if extending Object.prototype could be extremely comfortable in many situations, this is tipically considered one of the worst practices for every kind of purpose. The main reason is that everyone could write its own Object.prototype.doWhatEver method, destroying other libraries that could use another method with the same name or believe in for in loops without verifying the nature of the current key.

// generic object
var generic = {};   // same of var generic = new Object;

// typical for in loop
for(var key in generic){
    // nothing happens
    // generic has not keys
};

// modify Object.prototype with a method or a property
Object.prototype.someKey = "some value";

for(var key in generic){
    key;            // someKey
    generic[key];   // some value
};
            

Nowadays, we have a lot of different libraries that for this reason cannot coexists in the same context and working as expected. There is no official archive of dedicated or official pre defined Object.prototype methods, and even if some "not official yet" one is famous enough, for example the typical toJSONString Object.prototype, a lot of libraries developers still do not use the safe way to loop over a generic object.

// safe for in
for(var key in whatEverObject){
    if(whatEverObject.hasOwnProperty(key)){
        // do stuff with an explicit declared key
        // avoiding Object.prototype possible conflicts
    };
};
            

Accordingly, the first Object.prototype ever could be exactly this one:

Object.prototype.forIn = function(callback, self){
    for(var key in this)
        if(this.hasOwnProperty(key) && callback.call(self || this, this[key], key, this) === false)
            break;
};

// generic object
var	generic = {"a":"b"};

// forIn example
generic.forIn(function(value, key, object){
    // the forIn key will not be sent in this callback
    // only explicit keys and respective values
    value;              // b
    key;                // a
    object === generic; // true
});
            

At the same time, using above prototype could break libraries as well, for the same reason that if one of them has implemented a different version of Object.prototype.forIn, every iteraction will be broken by my forIn implementation. This is the basic paradox of prototypal inheritance, specially without "final" or "dontenum" declaration possibility, and the reason we probably would like to implement classical inheritance behavior, leaving Object.prototype as clear as possible.

top menu

Classes and classical inheritance basis

With classical inheritance we can create our instances with every kind of inherited prototype without affecting native Object one. In OOP oriented languages, the keyword class allows developers to create their own classes. With JavaScript 1.x, this keyword is reserved for future implementation (i.e. JavaScript 2) and the concept of a class is a bit different from other languages. In few words, a class is defined by a constructor, where a constructor is exactly a function. This is the first example of a constructor:

function /* class */ MyFirstClass(){
    // this scope is reserved to evey new instance
    // this is a function closure, and its behavior
    // is the same of every function
};

// this is an instanceof MyFirstClass declaration
var mfc = new MyFirstClass;

// true
(mfc instanceof MyFirstClass);
            

MyFirstClass is basically a function, but using the keyword new, before function name, will create an instanceof MyFirstClass (please read Note to know more). A function declaration, as MyFirstClass is, creates a dedicated prototype that inherits from its parent, in this case the Object and its prototype. This means that MyFirstClass will has a prototype to modify to create instances methods.

function /* class */ MyFirstClass(){};

// one or more prototype
// please note that MyFirstClass.prototype exists since
// MyFirstClass function creation
MyFirstClass.prototype.setValue = function(value){
    this.value = value;
};
MyFirstClass.prototype.getValue = function(value){
    return  this.value;
};

var mfc = new MyFirstClass;
mfc.setValue("some value");
mfc.getValue(); // some value
            

In other words, every instanceof MyFirstClass will inherit automatically every method or property assigned to MyFirstClass prototype. At the same time, every instanceof MyFirstClass will inherits methods or property setted in Object.prototype, that is why using this example we have just extended the native Object constructor with our MyFirstClass one. How to extend our constructor again?

function /* class */ MyFirstClass(){};
// add one or more prototype methods

function MyFirstSubClass(){};

// prototypal inheritance in action
MyFirstSubClass.prototype = new MyFirstClass;

var msc = new MyFirstSubClass;

// true
(msc instanceof MyFirstSubClass) && (msc instanceof MyFirstClass)
            

The prototype is an object, and an instanceof WhatEver is an object too, that is basically how we can assign an instanceof Something as prototype and extends them without problems. To better understand above example, we should think about a simple object like this one:

var generic = {};

// add one method to generic
generic.something = function(){};
            

When we add a method or a property to an object, we are using its dynamic get / set native behavior. Changing that object, we are not changing native Object.prototype but only an instanceof Object. When we assign an instanceof Something as prototype, we could change that prototype without affecting its original constructor prototype. This simply means that inherited prototype will be safe, and we will work only with an instanceof them.

function A(){};
function B(){};
B.prototype = new A;
B.prototype.imB = true;

var a = new A,
    b = new B;
b.imB;  // true
a.imB;  // undefined

// true
(b instanceof A) && (b instanceof B)

// true
(B.prototype instanceof A)

// going on with inheritance chain
function C(){};

// add dynamically a property or a method to b variable
b.imC = true;

C.prototype = b;

var c = new C;
c.imC;  // true

b = new B;
b.imC;  // undefined
            

What is happening is that every new instanceof "constructor", will inherit methods and properties in constructor.prototype. That is the reason we could implement prototypes using an object too:

function MyContainer(){};
MyContainer.prototype = {
    container:new Array,
    add:function(value){this.container.push(value)},
    count:function(){return this.container.length}
};

var c = new MyContainer;
c.add(1);
c.add(2);
c.count();  // 2
            

But we cannot do the same when we would like to extend another constructor.

function MyContainerAdvanced(){};

// to extend MyContainer we need to set
// an instanceof Container as prototype
// this code will work but MyContainerAdvanced
// will not inherits MyContainer prototype properties and methods
MyContainerAdvanced.prototype = {
    get:function(index){
        // this container does not exists in this object
        return this.container[index];
    }
};

// correct way
MyContainerAdvanced.prototype = new MyContainer;
MyContainerAdvanced.prototype.get = function(index){
    return this.container[index];
};
            

Are things a little bit more clear now? Inheritance is based on prototype. If used prototype is instanceof Something, every derived instanceof constructor that contain that prototype will be instanceof that constructor first, and instanceof its prototype (Something) secondly.

Note: if a constructor returns a value, the new keyword will generally override function nature. But if constructor return a new constructor, the result variable will be an instanceof returned instance constructor and not an instanceof called constructor.

function MyFirstClass(){
    // return generic (primitive) value
    return  1;
};

var mfc = new MyFirstClass();

// true     (mfc instanceof MyFirstClass)
// false    (mfc instanceof Number)


function MySecondClass(){
    // return a new instanceof something else
    return  new Number(1);
};

var mfc = new MySecondClass();

// false    (mfc instanceof MySecondClass)
// true     (mfc instanceof Number)
            

In both cases we are probably using a constructor in a bad way. We should know perfectly this behavior before we do, for example, something like this for IE < 7:

if(!window.XMLHttpRequest)
    XMLHttpRequest = function(){
        return  new ActiveXObject("Microsoft.XMLHTTP");
    };

// ready for Ajax?
var xhr = new XMLHttpRequest;
xhr.open( ... );
            

What is important to remember is that in this special case if we add prototype methods or properties to XMLHttpRequest, IE < 7 instances will not inherit those methods or properties.

top menu

A better classical inheritance with an intermediate constructor

There are a couple of omitted things in precedent examples. These things are foundamental for a lot of reasons, specially to make sense when we use prototypal inheritance to emulate classical one. The first thing to understand is that a constructor is a function, and as a function, it could contain different stuff.

function MyHEX(num){

    // nested private function
    function toHEX(num){
        return  "0x" + num.toString(16);
    };
    
    // privileged property
    this.value = toHEX(num);
};

// prototype properties / methods
MyHEX.prototype.toBase10 = function(){
    return  parseInt(this.value.substring(2), 16);
};

var	mh = new MyHEX(255);
mh.value;	// 0xff
mh.toBase10();	// 255
            

I will talk about private and privileged methods/properties later. What we could focus on now, are operations inside the constructor. Whatever these do, if I use precedent prototype assignment to extend MyHEX, i will create a prototype with an undefined value as part of the prototype.

// extend MyHEX
function MyOctal(){};
MyOctal.prototype = new MyHEX; // error
            

The reason we cannot extend MyHEX in that way is that if we do not specify an arguments for MyHEX constructor, it will try to convert an undefined value, in this case num variable, into a string using a toString method. The main problem is not undefined to String convertion, but the constructor itself. Since we could not know what constructor does, how many arguments it could accept, and what kind of arguments it expects, we can choose to extend them using directly its prototype. The only thing to take care about, is the reference to original MyHEX prototype. We do not want to change them, using a code like this one:

function MyOctal(){};

// assigne prototype by reference
MyOctal.prototype = MyHEX.prototype;

MyOctal.prototype.dedicatedValue = 123;
MyHEX.prototype.dedicatedValue; // 123
            

If we assign an object, or an instanceof Something, to another variable, we are basically creating a link to original object, using a different name. This means that above example will not let us add, change, or modify, MyOctal prototype, without changing MyHEX prototype too: both prototype are linked to the same object. To solve this problem (that is only an expected behavior), we have two options: clone manually the prototype, or use an intermediate constructor to create another chain in the inheritance. The first solution is not possible for the same purpose, because we could copy every method or property, but at the end we are not truly inheriting from MyHEX constructor.

function MyOctal(){};

// manual prototype assignment
// (this time we could not care about Object.prototypes, they will be assigned anyway)
for(var	key in MyHEX.prototype)
	MyOctal.prototype[key] = MyHEX.prototype[key];

// we have every MyHEX method or property, but not a MyHEX instance as prototype
var mo = new MyOctal;

// false
(mo instanceof MyHEX);
            

So, object clone is not really the solution, while intermediate constructor is exactly the one that will let us truly extend MyHEX constructor.

// intermediate constructor
function Intermediate(){
    // this constructor has to be void
    // no operations inside them
};

// assign MyHEX prototype by reference
Intermediate.prototype = MyHEX.prototype;

// Intermediate has same prototype of MyHEX
// but its constructor does not contain operations
// we can create an instanceof Intermediate function
// without operations and/or arguments paranoia
MyOctal.prototype = new Intermediate;

// true
((new MyOctal) instanceof MyHEX);
            

Creating a new instance of Intermediate void constructor, we are inheriting MyHEX prototype, because it is the same of Intermediate one. As we have seen before, an instance can have one or more methods or properties thanks to its dynamic behavior, and without affecting its constructor prototype. This means that after MyOctal.prototype assignment, we could add, modify, or change that prototype without affecting original one. The intermediate strategy has been described by Douglas Crockford in his famous Prototypal Inheritance in JavaScript article. In that article, the aim of this strategy is totally different, but the same strategy is perfect to extends constructors as well. The big difference between his example and above one, is that in mine we can better understand why that function is called intermediate. In fact, every instanceof MyOctal will be an instanceof Intermediate and then an instanceof MyHEX. To obtain the same result using a basic extend function, we could use this simple snippet:

// basic extend function
function extend(B, A){
    function I(){};
    I.prototype = A.prototype;
    B.prototype = new I;
    B.prototype.constructor = B;
};

function MyOctal(){};
extend(MyOctal, MyHEX);

MyOctal.prototype.doStuff = function(){
    // method inherited only by MyOctal instances
};

// ... other code ...
            

Using a function like extend, we can create inside its closure our Intermediate constructor and assign an instanceof them as B prototype. It is not necessary to obtain the nested function, because it is used only as a bridge between one prototype and a new instance based on that prototype. Above example shows another foundamental thing to consider in prototype based classical inheritance emulation, the constructor property.

Note 1: the intermediate function is not a problem for performances. In the prototype look back inheritance, if a method is not present in constructor.prototype, looking for Intermediate.prototype will be the same thing of looking for parent.prototype, MyHEX in showed example.

Note 2: every time we use an extend function, we are creating an empty constructor that will persist in the memory. For leaks maniacs, this is not truly a problem for memory usage, because an empty constructor cannot increase them consistently. On the other hand, this is the only one way we have to truly extend another constructor, so please be tollerant.

top menu

Never forget the constructor property!

One of the most important properties of a generic variable, is its constructor. The constructor property is the one that contains, as word says by itself, the variable constructor. In the native Object.prototype, for example, the constructor is Object. In every number, constructor is Number, while in every string, the constructor is String. Because of "primitive but not only" variable ambiguity, constructor is virtually the unique way to recognize a variable type. In other languages, the constructor property could be compared as a get_class function, or __class__, or whatever it is. That is why constructor is absolutely important to respect and, when it is necessary, to assign.

// primitive VS instance
var pStr = "test",
    oStr = new String("test");

// false
(pStr === oStr);

// false
(pStr instanceof String);

// false
(typeof oStr === "string");

// true!
(oStr.constructor === pStr.constructor);
            

Above example shows how much constructor is important to simplify variable type recognition. Since every native variable or instance contains its correct constructor, why should we break this natural behavior when we create a prototype?

function MyConstructor(){};
MyConstructor.prototype = {
    doStuff:function(){
        // whatever we need ...
    }
};

var mc = new MyConstructor();

// true!
(mc.constructor === Object);
            

Above example shows an absolutely expected behavior that is basically illogical. If I create an instanceof MyConstructor I would expect exactly MyConstructor as instance constructor. Why should I have a generic Object constructor? The answer is extremely simple: Object.prototype contains a property called constructor that is exactly the Object one. If we assign a prototype using an object, instead of using the prototype itself, we are overriding MyConstructor.prototype default constructor property, setting the one inherited from Object.prototype, thanks to {} assignment.

var o = {};

// true
(o.constructor === Object);
            

Accordingly, if we want mantain expected constructor, we just have to explicitly declare them inside our runtime created object.

function MyConstructor(){};
MyConstructor.prototype = {
    constructor:MyConstructor,
    doStuff:function(){
        // whatever we need ...
    }
};

var mc = new MyConstructor();

// hooray!
(mc.constructor === MyConstructor)
            

Every time we want to extend something, or assign a prototype, we could better remember to assign the constructor, because it is used in a large amount of scripts for dynamic operations and it is, absolutely, important.

function A(){};
function B(){};
B.prototype = new A;
B.prototype.constructor = B;
            

Following this basic rule, our code will be automatically more clear, portable, scalable, and finally compatible (please do not be so lazy!).

// one day, if everyone will remember the constructor ...
switch(value.constructor){
    case    Array:
    case    Boolean:
    case    Date:
    case    Function:
    case    Number:
    case    String:
    case    Object:
        // do stuff with native constructor instances
        // ... if noone forgot the constructor ...
        // otherwise we cannot know what kind of variable is it
        // and instanceof is not a good solution for native constructors.
        // So, why create problems instead of make things more simple for everyone?
        break;
    case    Base:
        // do stuff
        break;
    case    Class:
        // do stuff
        break;
    case    dojo.Derived:
        // do stuff
        break;
    case    DOMAssistant:
        // do stuff
        break;
    case    jQuery:
        // do stuff
        break;
    case    MyOwnConstructor:
        // do different stuff
        break;
    case    YUI.Util.Class:
        // do stuff
        break;
};
            

Finally, we could say that every time we create a constructor, or more generically a function, the browser's JavaScript engine will assign a new object as prototype with correct constructor as default property.

function A(){};
// we could consider that JavaScript core will istantly assign
// something like next object as A default prototype
// A.prototype = {constructor:A};

// true
(A.prototype.constructor === A);
            

Of course this is not exactly what the core does, but if we think about them, we will probably remember the constructor every time (if not, try to eat more fish, it is good for memory too!). As last example about classical inheritance, look at these assertions, after above code:

// true, prototype inherits from Object.prototype
(A.prototype instanceof Object);

// false
// A constructor creates instanceof A but its prototype natively inherits from Object
(A.prototype instanceof A);
            

Basically, above example shows the rule of prototypal inheritance, if a constructor.prototype is instanceof SomethingElse, every constructor derived instance will be instanceof that constructor and an instanceof of constructor.prototype constructor too (SomethingElse).

top menu

Privileged properties and methods

Privileged properties and methods are in a separate layer between instance creation and its usage. During instance creation the returned variable is inheriting from its constructor prototype. After them it will be injected inside the constructor itself and finally it will be assigned.

// basic constructor
function Person(name){
	if(name)
		this.name = name;
};
// by default each instanceof Person has a name
// but if it is not sent to constructor
// we do not know who is this person
Person.prototype.name = "unknown";

// this is what we do - line 1
var me = new Person("Andrea");
// line 2 ... me instance is ready


// while this is what is virtually happening ... on line 1

// instance initializzation
meNotYet = instanceof Person constructor

// prototype inheritance
for(key in Person.prototype)
	meNotYet[key] = Person.prototype[key]
// now meNotYet has a property, name, with value "unknown"


// call constructor with used arguments
Person.apply(meNotYet, arguments);

// privileged variable assignment
// overwrite property because of arguments[0]: "Andrea"
meNotYet.name = value;

// assignment to me variable
var me = meNotYet

// line 2 ... 
me.name; // Adrea

// of course, now we could change that property again
me.name += " Giammarchi";
			

As we can see in above example, privileged variables, or methods, are assigned when prototype has just been inherited.

function Person(name){
	// here this.name will be always "unknown"
	if(name)
		this.name = name;
		// but we can overwrite them before
		// variable assignment
};
Person.prototype.name = "unknown";
			

The main difference between privileged properties or methods, is that for each created instance the constructor will create many functions or properties as specified, while prototype is shared for every instance, and it does not create a different scope or value.

function Person(){
	// privileged method
	this.setName = function(name){
		this.name = name;
	};
};
Person.prototype.name = "unknown";
Person.prototype.getName = function(){
	return	this.name;
};

var me = new Person();
// me has an inherited getName method
// me has a privileged setName method

var daniele = new Person();
// daniele exactly the same me getName method
// daniele has a privileged setName method

// this is true, method getName is shared
(me.getName === daniele.getName);

// and this is true again
(me.getName === Person.prototype.getName);

// while this is false, setName is a new different function
// for each instance
(me.setName === daniele.setName);
			

If each instance will create a new setName method, after 100 instance we will have in memory 100 setNames functions, plus one single getName function. This is basically the reason to prefere always a prototype method instead of a privileged one. Only properties assigned during instance declaration, using constructor arguments, should be allowed inside the constructor. So why someone still use privileged methods inside constructors? The answer is in the next paragraph.

top menu

Private methods

Everyone knows what does private mean, and in JavaScript a private variable, function, method, and constructor, is everything that persist, or not, in a dedicated scope instead of global one. This behavior is simply implementable using a closure, where a closure is a function that wrap its content in this way:

// global window scope
function closure(){
	// internal function scope, start
	function onlyhere(){
		return	123;
	};
	var closure = onlyhere();
	// internal function scope, end
};

// everyone can use the closure function
colsure(); // same of window.closure(); or this.closure(); or self.closure();

// but noone can access to private variable
closure.closure; // undefined, closure is not a static public function variable
closure().closure; // error, closure returns undefined
// and undefined cannot contain a "closure" property
// the same is for onlyhere function
			

Everytime we will use above closure function, this will create another function, called onlyhere, plus a variable, called closure. But at the end of the function, the garbage collector will remove as soon as possible both onlyhere and closure, because nothing else could access to these property or function. We could call them private variables or private functions, and these could be used inside constructors as well.

function Person(){
	// constructor closure {{{

	// private function
	// only functions or variables
	// that are in this closure
	// can use this function
	function setName(name){
		this.name = name;
	};
	
	// privileged method
	// uses the same closure of setName function
	this.setName = function(name){
	
		// to use private setName as method
		// we have to inject our instance scope
		setName.call(this, name);
	};
	
	// }}} constructor closure
};

var me = new Person;
me.setName("Andrea");
me.name; // Adrea
			

Even if this example is redundant and does not make sense (two methods to do one simple thing), this is a basic private method example. Everyone can access to instance.setName privileged method, but noone will be able to use function setName inside the constructor. Private methods help developers do mantain API more clear, delegating internal operations to methods that noone outside should be able to use. At the same time, private methods are safe because changing prototype or adding an instance method, will not affect private functions. But the most important thing to remember is that now, every single Person instance, will create two functions, and garbage collector will never remove function setName until instance is not destroyed. Of course it is necessary because instance could use setName privileged method every time, and it contains a call to setName function. Basically, this means that if we create 100 instances of Person, we will have 200 different functions in memory. This is really a bad code design for performances, that is why we should not use constructors as private methods containers. What we should do, is to use the prototype to share private methods too. And here there is an example:

// same behavior, based on prototype
function Person(){};

// runtime executed closure
(function(){
	
	// private method
	function setName(name){
		this.name = name;
	};
	
	// prototype
	Person.prototype.setName = function(name){
		setName.call(this, name);
	};
	
})(/* these brackets call istantly the precedent closure function */);

var me = new Person;
me.setName("Andrea");
me.name; // Adrea
			

Noone, outside that runtime closure, will be able to use function setName, while the prototype, created in the same closure, will be able to use them everytime. The main goal of this different approach to create private methods is that for 100 instances of Person, we will have in memory only three functions and never more. These three functions are the runtime closure, the function setName, and finally the public prototype setName method.

top menu

Private properties

Private methods are simple to implement, and simple to use as well. We can even extend without special efforts a constructor that uses private methods, but it is not exactely the same thing with private properties. As we know, a prototype is an instance, and an instance can obviously contain a link to a private variable.

// runtime closure
(function(){
	// without usage of var, this variable will be global
	myObject = {};
	
	// using var, this variable will exists only in this scope
	// and nested scopes, if any
	var	_private = 123;
	
	myObject.getPrivate = function(){
		// this scope is nested into closure
		// we can acess to private variable
		return	_private;
	};
})();

myObject.getPrivate(); // 123
			

Really simple, isn't it? Every time we will call getPrivate dynamic method we will recieve number 123. There is no way to change that number, because myObject has no methods to do it. But what is happening if we do something like this?

(function(){
	var	_private = 123;
	myObject = {
		getPrivate:function(){return _private;},
		setPrivate:function(value){_private = value;}
	};
})();

myObject.getPrivate(); // 123
myObject.setPrivate(456);
myObject.getPrivate(); // 456
			

Everything seems to work as expected. Now we can set or get that private value. Well, now try to imagine that myObject could simply be a prototype:

(function(){
	var	_private = 123;
	myObject = {
		getPrivate:function(){return _private;},
		setPrivate:function(value){_private = value;}
	};
})();
function MyNumber(){};
MyNumber.prototype = myObject;
MyNumber.prototype.constructor = MyNumber;

var	num1 = new MyNumber(),
	num2 = new MyNumber();

num1.getPrivate(); // 123
num2.setPrivate(456);
num1.getPrivate(); // 456

myObject.getPrivate(); // 456
			

This behavior is absolutely normal, because every instanceof MyNumber will share its prototype methods. These are myObject methods, created once inside a closure. So, every instance will virtually use myObject methods. Accordingly, every instance will use that private variable too. There is no way to change this behavior, extending or not that constructor. At this point, a possible solution to use unshared private variables, is to create them inside the constructor for each instance. But at the same time, we will need to create a privileged public (or protected) method that will be the "bridge" to access to that variable from prototype methods too.

function Person(name){
	// privileged method
	this.getName = function(){
		return	name;
	};
};
Person.prototype.getNamePlusSurname = function(surname){
	return	this.getName() + " " + surname;
};

var me = new Person("Andrea");
me.getNamePlusSurname("Giammarchi"); // it's a me!
			

This will cause the same problem described in privileged methods, for 100 instances of Person, we will have in memory 100 privileged functions, and 100 different "name" variables as well. At the same time, this is (probably) the only way we have to avoid private shared variables behavior.

top menu

Protected properties and methods

In classical inheritance a protected method, or property, is something that cannot be used outside the instance, as public methods or properties, but that can be used by constructor that extends those methods. This example shows an ipotetical protected behavior:

function Person(){
	// we can use protected method
	this._setName("unknown");
};
/* protected */ Person.prototype._setName = function(name){
	this.name = name;
};

// please note that a new Person
// has a name property assigned in Person constructor
// using protected _setName method.
// If used as prototype, it will contain a name property
// with "unknown" string value.
// this is not true if we use precedent simple extend function.
// where constructor is not used

function Daniele(){
	// we can use inherited protected method
	// overriding inherited name property
	this._setName("Daniele");
};
Daniele.prototype = new Person; // Person used _setName protected method
Daniele.prototype.constructor = Daniele;

var daniele = new Daniele;
daniele.name; // Daniele

// next operation is possible in JavaScript
// but it is not possible with languages
// that support correctly protected methods
daniele._setName("Poldo");
			

Unfortunatly, there are not solutions (yet) to truly implement protected behavior. One similar way is described in this page, but it is only a personal experiment and code execution time could be drammatically improved. Anyway, it is a good practice to call virtually protected methods or properties with this char "_" as prefix. In this way we could make code readability more simple for everyone, understanding which method or property is teorically protected or not simply looking at its name.

top menu

Anonymous instance as prototype

We have seen how to create closures for private methods or properties, but there is another way to assign a prototype: the anonymous function. Since every constructor is a function, and every function that does not return a new instanceof SomethingElse could be used as constructor, it could be natural to create a prototype in this way:

function Person(){};
Person.prototype = new function(){

	// public properties
	this.constructor	= Person;
	this.name		= "unknown";

	// public methods
	this.getName	= function(){
		return	this.name;
	};
	this.setName	= function(name){
		_setName.call(this, name);
	};
	
	// private methods
	function _setName(name){
		this.name = name;
	};
};

var	daniele = new Person;
daniele.setName("Daniele");
daniele.getName(); // Daniele
			

Performances will be the same of regular prototype objects but, at least in my opinion, readability is definitively better than before. In one single step we can create a closure, an instance to use as prototype, and thanks to the closure, a place to put private methods or, if necessary, variables. This technique could be particulary indicated to create a sort of unique instance too, that will be the only one during its lifetime in our scripts.

var	unique = new function(){
	// just do it to avoid creation
	// of other instances with the same
	// constructor
	this.constructor = Object;
	
	// but if for some reason we need to reuse
	// this constructor, we can save them
	var	_constructor = arguments.callee;
};
			

Overwriting constructor property, we will basically hide forever that anonymous function. We cannot even know which instanceof is exactly that unique variable, Object a part, and it could contain private or public stuff without problems. This is only a particular case, useful if we have an instance and we do not want that other scripts will be able to recognize, use, or parse, its constructor.

top menu

Native constructors exception

There are different exceptions in JavaScript that sometime do not make sense. These exceptions usually depend on browser JavaScript engine implementation. But there is a particular exception that seems to be valid for every browser engine, the missed possibility to truly extends native constructors.

// try to extend one native constructor
function MyString(){
	// call super constructor
	String.apply(this, arguments);
};
// inherit String
MyString.prototype = new String;
MyString.prototype.constructor = MyString;

// one broken istance ...
var ms = new MyString("test");
ms.length; // error, undefined, or 0
			

It is really hard to extend Array, Boolean, Date, Number, String, or another native constructor. Accordingly, do not use the simple extend function with a native constructor. As sum, the day we will be able to truly extend them will probably never arrive for version 1 of JavaScript, while version 2 should be able to do it without problems. This is the main reason everyone would like to extend native constructors and a lot of developers have conflicts with other libraries too.

top menu

Classical inheritance patterns

Using a mixin of private variables and functions, prototypes, and a bit of OOP knowledge, we can implement a lot of common design patterns. For example, this is the Singleton one:

// JavaScript Singleton pattern
Function.prototype.singleton = function(){

    // if it is the first time we ask for the singleton
    if(!this._singleton){

        // create an Intermediate constructor
        // to avoid problems during initializzation
        // of the generic constructor itself
        function I(){};

        // assign the same prototype to extend itself
        I.prototype = this.prototype;

        // create the singleton instance
        this._singleton = new I;
        
        // we do not need to redeclare the instance constructor
        // this time we are extending the constructor itself
        // to finally call the constructor itself using apply method
        
        this.apply(this._singleton, arguments);
    };

    // return singleton in every case
    return  this._singleton;
};

// basic example using a simple Person constructor
function Person(name, gender, age){
    this.name   = name;
    this.gender = gender;
    this.age    = age;
};

Person.prototype.toString = function(){
    return  this.name + ", gender " + this.gender + ", is " + this.age + " years old";
};

// retrive the instance for the first time
var me = Person.singleton("Andrea", "male", 29);
me.name += " Giammarchi";

// retrive the same instance
var meWherEver = Person.singleton();
meWherEver; // Andrea Giammarchi, gender male, is 29 years old

// true
(me === meWherEver && me instanceof Person);
            

Above code will work with every constructor except for natives. For some reason, even if the logic of this code does make perfectly sense, not every browser let we use call, or apply, with native constructors. We can test directly by ourself with this code:

Boolean.singleton(true); // error

var a = [];
Array.call(a, 1, 2, 3);
a; // empty array
			

We know this page has been written to explain JavaScript inheritance, and not to solve engines problems. Anyway, for this case, and why not for other cases too, we could use evil code evaluation:

// create a closure for a private function
(function(){

	// transform arguments into a string
	function args(arguments){
		for(var	i = 0, length = arguments.length, args = []; i < length; i++)
			args[i] = "arguments[" + i + "]";
		return	args.join(",");
	};

	// singleton design pattern
	Function.prototype.singleton = function(){
		return	this._singleton || (this._singleton = eval("new this(" + args(arguments) + ")"));
	};

	// to recycle args function, we could implement other patterns that need them
	// this is, for example, a simple version of factory design pattern
	Function.prototype.factory = function(){
		return	eval("new this(" + args(arguments) + ")");
	};
})();

// singleton example
var	a = Array.singleton(1,2,3);
a.push(4,5,6);
var	b = Array.singleton();
b;	// 1,2,3,4,5,6
var	c = Array.singleton(7,8,9);
c;	// 1,2,3,4,5,6
c === a;// true

// factory example
var	a = Array.factory(1,2,3),
	b = Array.factory(4,5,6);
a;	// 1,2,3
b;	// 4,5,6
			

Note: for Rhino users, or developers that cannot use eval function, try with this code:

// replace this piece of code in both prototypes
eval("new this(" + args(arguments) + ")")

// with this one
Function("return new this(" + args(arguments) + ")").apply(this, arguments)
			

top menu

A better extend function proposal

The basic extend function showed in a better classical inheritance paragraph could be easily improved to become a Function prototype and to add a particulary useful feature. A lot of languages based on classical inheritance, have a super keyword to use parent methods. Using a protected naming convention, we could add this feature directly into extend function prototype. The goal is to avoid manual ConstructorName.prototype.methodName usage and to be able to do something like this:

function Person(first, last) {
	this.first	= first;
	this.last	= last;
};
Person.prototype.toString = function() {
	return	this.first + " " + this.last;
};

function Employee(first, last, id){

	// call the super constructor
	// will set first and last properties
	this._super(null, first, last);
	
	// we could do the same manually ...
	// Person.call(this, first, last);

	// add another property
	this.id = id;
};

extend(Employee, Person);
Employee.prototype.toString = function(){
	// call the super method and add other informations
	return	this._super("toString") + ": " + this.id;
	
	// we could do the same manually ...
	// return Person.prototype.toString.call(this) + ", id: " + this.id;
};

var	me = new Employee("Andrea", "Giammarchi", 12345);
me.toString(); // Andrea Giammarchi, id: 12345
			

In the inheritance chain every constructor.prototype._super should be able to call the first available parent method or constructor, if any. To obtain this behavior, we could use a prototype like this one:

// this prototype accepts one or two arguments
// if the first one is a function, it is used as super
// otherwise it is used as prototype
Function.prototype.extend = function(_super, proto){
	var	hasSuper = typeof _super === "function",
		key;
	
	// there is a constructor to extend
	// let do Intermediate stuff
	if(hasSuper){
		function I(){};
		I.prototype	= _super.prototype;
		this.prototype	= new I;
	} else
		// super is not a function
		// we suppose this has been sent as prototype
		proto = _super;
	if(proto){
	
		// assign every method from proto instance
		for(key in proto)
			this.prototype[key]	= proto[key];
		
		// some browser does not include constructor, toString, and valueOf keywords
		// inside a for in loop, even if these are explicitly declared
		if(proto.hasOwnProperty("toString"))
			this.prototype.toString	= proto.toString;
		if(proto.hasOwnProperty("valueOf"))
			this.prototype.valueOf	= proto.valueOf;
	};
	
	// if there is a super, we create
	// the prototype that will make magic happen
	if(hasSuper)
	
		// this prototype accepts zero or more arguments
		// if the first argument is a nullable value (undefined, false, 0, "", null)
		// this function will call directly the constructor
		// while if name is a string, this function will call
		// super method with that name (if any, otherwise it will rightly raise an error)
		this.prototype._super = function(name){
			var	_rem	= this._super,
				result;
			// to continue with inherited chain
			// the _super property has to be
			// setted as the one stored in parent constructor prototype
			this._super	= _super.prototype._super;
			// this is because inside super method we would like to be able
			// to use again the magic _super with parent constructor or method as well
			result		= (name ? _super.prototype[name] : _super).apply(this, Array.prototype.slice.call(arguments, 1));
			
			// after constructor or parent method execution
			// we have to set the original super to be able
			// to call this method another time
			this._super	= _rem;
			
			// operation result
			return	result;
		};

	// remember the correct constructor
	this.prototype.constructor	= this;

	// to make things more simple, return the function itself
	return	this;
};
			

With a prototype like this one we could create a chain in a really simple way:

Employee = (function(first, last, id){
	this._super(0, first, last);
	this.id = id;
}).extend(
	Person = (function(first, last){
		this.first	= first;
		this.last	= last;
	}).extend(
	{	// Person prototype
		toString:function(){return	this.first + " " + this.last;}
	}),
	{	// Employee prototype
		toString:function(){return	this._super("toString") + ", id: " + this.id;}
	}
);

var	me = new Employee("Andrea", "Giammarchi", 12345);
me.toString(); // Andrea Giammarchi, id: 12345
			

One interesting thing about functions, is that we do not usually use their name but it could be really important or useful. If we declare a function normally, it will probably contain its name if used browser is, for example, FireFox.

function I(){};
I.name; // I

var	I = function(){};
I.name; // "" ... empty string
			

When we do not need an inline function, a closure, or an inline instance creation, we could prefere regular function declaration. However, this is only a not standard related suggestion, but that is why I prefere to write a better and more clear example like this one:

function Person(first, last){
	this.first	= first;
	this.last	= last;
};
Person.extend({
	toString:function(){return	this.first + " " + this.last;}
});

function Employee(first, last, id){
	this._super(0, first, last);
	this.id	= id;
};
Employee.extend(
	Person, {
	toString:function(){return	this._super("toString") + ", id: " + this.id;}
});

function Manager(first, last, id, department){
	this._super(0, first, last, id);
	this.department	= department;
};
Manager.extend(
	Employee, {
	toString:function(){return	this._super("toString") + ", department: " + this.department;}
});


var	daniele = new Manager("Daniele", "DielleElle", 3, "IT");
daniele.toString(); // Daniele DielleElle, id: 3, department: IT
			

top menu

Some post it

In this paragraph I will try to put more examples or solutions based on requestes (if any).

Privileged methods or properties are not automatically inherited using my two extend proposal. More generally, everything that is inside a constructor is never directly inherited or, if we do not use intermediate strategy, the prototype instance will contain privileged stuff declared only during its assignment, as showed in Person.prototype._setName example in protected paragraph. To avoid problems, we should call them explicitly. Otherwise we could have some problem:

function A(value){
	// privileged method
	this.getValue = function(){
		return	value;
	};
};
A.prototype.toString = function(){
	return	String(this.getValue());
};

function B(){};
extend(B, A);
// or B.extend(A);

var	b = new B("test");
b.toString(); // error, getValue is not a function
			

Obviously the B constructor does not contain A stuff. If we do not explicity call the A one, its privileged getValue method will not be usable. To obtain expected result you just need to write this:

function B(name){
	A.call(this, name);
	
	// or A.apply(this, arguments);
	
	// with extend.prototype ...
	// this._super(0, name);
	// or ...
	// this._super.apply(this, [0].concat(Array.prototype.slice.call(arguments, 0)));
};
extend(B, A);

var	b = new B("test");
b.toString(); // test
			

The private property behavior could be used to share an information with every instance, or constructor itself, as common prototype methods or properties do.

function Item(){
	this._increment();
};
Item.prototype = new function(){
	
	// private shared property
	var	_total = 0;
	
	// "protected" prototype
	this._increment = function(){
		++_total;
	};
	
	// public method and/or public static method
	this.many =
	Item.many = function(){
		return	_total;
	};
	
	// constructor!
	this.constructor = Item;
};

var	one = new Item,
	two = new Item;

one.many(); // 2
two.many(); // 2

var	three = new Item;

one.many(); // 3
Item.many(); // 3
			

What we could not forget is that if we will extend Item constructor, every sub constructor will inherit those methods from the same scope. So every new instance of an extended Item constructor, will increment _total shared variable if it will call parent constructor.

function SubItem(){
	Item.call(this); // _total will be increased
};
			

The same thing will happen if we do not explicity call Item constructor but, for some reason, we will use protected _increment method.

function SubItem(){};
extend(SubItem, Item);
SubItem.prototype.init = function(){
	this._increment(); // _total will be increased
};

var	si = new SubItem;
si.init();
Item.many(); // 4, considering one, two and three precedent instances
			

About the first singular case where Object.prototype is not an instanceof Object, we could basically think that this respects perfectly the protypal inheritance concept. Every instanceof Object is a new Object, but its prototype inherits from SomethingElse, in this case a sort of basic constructor that rappresent the origin of every "class". Accordingly, Object.prototype contains a redefined constructor property that is Object itself, so we cannot access to original constructor, but we can inherit them in every other prototype.

//true
(String.prototype instanceof Object);
			

This is the end of our trip around JavaScript prototypal inheritance. Please do not hesitate to write a comment or a suggestion in my blog dedicated post (... and it does not necessary require subscription). Kind Regards.

top menu