Inheritance is a useful pattern for code reuse, however there isn’t one single way of expressing inheritance in JavaScript.
Two of the inheritance patterns that can be used in JavaScript are constructor functions, which resemble the kind of inheritance that most programmers with a Java/C++ background are use to, and prototypal inheritance, a pattern in which inheritance is expressed as objects inheriting directly from other objects.
Constructor Functions
Define an object by writing a constructor function and then create an instance of it by using new. The convention is that the names of constructor functions should be capitalized so that programmers know that they should be called with new.
// A constructor called Animal with a property called name
// Functions which are constructors are called with new
// The names of constructors should be capitalized
var Animal = function(name) {
this.name = name || 'no name';
};
// Instances of Animal have a public method called
// get_name
Animal.prototype.get_name = function() {
return this.name;
};
// An example of using Animal
var creature = new Animal("creature");
document.writeln("Animal name: " + creature.get_name() + "");
To express inheritance, replace the prototype of the derived object with the object you want it to derive from.
Here we describe an Animal object which has a property called name and a method get_name(). The Cat object inherits from Animal and adds a sound property defined as ‘meow’ and a method get_sound() which returns this sound.
// Define an object Cat
var Cat = function(name) {
Cat.prototype.constructor.call(this, name); // Call Animal's constructor function
this.sound = 'meow';
};
// Replace Cat's prototype with Animal to express the inheritance
Cat.prototype = new Animal();
// Cat's prototype has its own public method in addition
// to what it inherited
Cat.prototype.get_sound = function() {
return this.sound;
};
var myCat = new Cat("myCat");
document.writeln("Cat name: " + myCat.get_name() + ""); // myCat
document.writeln("Cat sound: " + myCat.get_sound() + ""); // meow
The JavaScript documentation at Mozilla has more details and examples of constructor functions.
Prototypal Inheritance
JavaScript is a prototypal language and there are no classes, only objects. It is a loosely typed language and so casting does not exist and the type hierarchy is not relevant.
In JavaScript: The Good Parts, Crockford writes,
JavaScript, being a loosely typed language, never casts. The lineage of an object is irrelevant. What matters about an object is what it can do, not what it is descended from.
To take advantage of this, prototypal inheritances involves first defining a useful object which has properties/methods in common with other objects and then using Object.create() to create another similar object.
Here we define an object called myPetCat with a name of ‘Kitty’, a method get_name() which returns this name and a method get_sound() which returns ‘meow’. Then we define a similar object myOtherPetCat which is identical to Kitty except this object has a different name ‘Felix’;
// Define a useful object
var myPetCat = {
name : 'Kitty',
get_name : function() {
return this.name;
},
get_sound : function() {
return 'meow';
}
};
// Define a new object based on the former
var myOtherPetCat = Object.create(myPetCat);
myOtherPetCat.name = 'Felix';
document.writeln("Pet cat name: " + myPetCat.get_name() + ""); // Kitty
document.writeln("Pet cat sound: " + myPetCat.get_sound() + ""); // meow
document.writeln("Other pet cat name: " + myOtherPetCat.get_name() + ""); // Felix
document.writeln("Other pet cat sound: " + myOtherPetCat.get_sound() + ""); // meow
More inheritance
These are just two of ways of expressing inheritance in JavaScript. Douglas Crockford describes other methods in his book JavaScript: The Good Parts, one of the highly recommended JavaScript books.