Inheritance in JavaScript

This post hopes to shed some light on the Object-Oriented nature of JavaScript and how to implement inheritance in JavaScript first via a ‘classical’ form and then followed by the ‘prototypal’ variation that comes as standard in JavaScript.

Scripting vs Programming

JavaScript is a ‘scripting‘ language. Scripting languages are different from traditional ‘programming‘ languages in that you don‘t have to compile your code to make your program run.

Object-Oriented Programming

Programming languages such as Java implement a paradigm known as Object-Oriented Programming (OOP). OOP encourages two fundamental principles:

  1. code reuse
  2. type system

Classes?

In ‘classical‘ OOP languages, objects are instances of classes and classes can inherit from other classes.

A ‘class‘ is basically a blueprint.

For example, you could create a class called ‘Dog‘ which would define all the characteristics of that animal. You could then create a new ‘instance‘ of the ‘Dog‘ class and assign it to an object.

e.g. create a new instance of the ‘Dog‘ class and assign it to an object called ‘Labrador‘.

‘Labrador‘ would then inherit all the properties of the ‘Dog‘ class.

This makes your code more efficient as you don‘t have to keep creating objects with the same properties and methods, you can create objects that inherit from a base class.

If the concept of OOP is new to you then the Java website has a good list of articles on OOP and its implementation using the Java language (although the articles are written for Java developers, the core concepts of OOP are the same no matter what language you choose to use).

Prototypal Inheritance

JavaScript does implement a form of inheritance, but not the classical form of inheritance you may be used to if you come from an OOP language such as Java (or even C# or PHP5+).

JavaScript actually utilizes what is known as ‘Prototypal‘ inheritance.

What this means is that in a prototypal system, objects inherit from objects.

So where as in ‘classical‘ languages you would define a class and then create a new instance of that class, in JavaScript we instead create an object. Another object can then inherit the properties/values of that first object by linking to it via what is called the “prototype chain”.

The Mozilla Developer Centre has a useful article which explains further the differences between Class based languages and Prototype based languages.

In my opinion JavaScript is an incredibly rich scripting language and its implementation of prototypal inheritance is much more efficient than ‘classical‘ style inheritance.

Time for some code examples

The following code demonstrates how you can recreate ‘classical‘ style inheritance in JavaScript.

function Extend(subclass, superclass)
{
	// Define a private function
	function F(){}
 
	/*
	 * This means that any new instances of "F"
	 * will have their prototype pointing to the superclass prototype.
	 */
	F.prototype = superclass.prototype;
 
	/*
	 * The following code basically means that any new instances of the subclass
	 * will mean its prototype will point to the "F" instance.
	 *
	 * The prototype for "F" then points to the superclass' prototype.
	 * This means that changes to superclass.prototype will
	 * propagate to all subclass instances (through the inheritance chain).
	 *
	 * Also, because we have created a 'new' object for
	 * the subclass' prototype property (i.e. we've created a new instance of F() rather than just point to the prototype object),
	 * we can add to subclass.prototype without affecting the superclass prototype.
	 */
	subclass.prototype = new F();
 
	/*
	 * Also, whenever you create a new object instance in JavaScript,
	 * that instance's local "constructor" property points to
	 * the function (Constructor) that was invoked to create the instance.
	 *
	 * But sometimes this property can display the incorrect data.
	 * So to prevent any confusion when it comes to checking an instance's constructor value (for the purposes of type checking)
	 * it is best to reset the constructor property to point to the subclass constructor.
	 */
	subclass.prototype.constructor = subclass;
 
	/*
	 * The final two lines are used as convenience properties
	 * when invoking ancestor constructors and methods.
	 */
	subclass.superclass = superclass;
	subclass.superproto = superclass.prototype;
}
 
function Person(name, age)
{
	this.name = name;
	this.age = age;
}
 
function Employee(name, age, department)
{
	Employee.superclass.call(this, name, age);
	this.department = department;
}
 
/*
 * Call the Extend function
 * (which ensures "Employee" inherits from the "Person" object/class)
 */
Extend(Employee, Person);
 
// Add a new method to the Employee object/class
Employee.prototype.display = function()
{
	console.log(this.name + "\n" + this.age + "\n" + this.department);
};
 
// Create a new instance of the Employee object/class.
var employee = new Employee("Mark McDonnell", 27, "Digital Media");
 
// Display the "employee" data
employee.display();

Now the next piece of code demonstrates how you can use prototypal inheritance.

function Clone(object)
{
	function F() {}
 
	/*
	 * If any method or property lookup on the current Object instance fails,
	 * that lookup will then look to the prototype object
	 */
	F.prototype = object;
	return new F;
}
 
var Person = {
	name: null,
	age: null,
	getName: function()
	{
		return this.name;
	},
	getAge: function()
	{
		return this.age;
	}
};
 
/*
 * To create Author, you don’t make a subclass of Person.
 * Instead you make a clone:
 */
var Author = Clone(Person);
Author.books = [];
Author.getBooks = function()
{
	return this.books;
};
 
// Now create some more objects based on "Author"
var author = [ Clone(Author), Clone(Author) ];
 
author[0].name = "Mark McDonnell";
author[0].age = 27;
author[0].books = ["Book 1","Book 2"];
 
author[1].name = "Joe Bloggs";
author[1].age = 39;
author[1].books = ["Book A","Book B","Book C","Book D"];
 
// Display the "author" data
console.log(author[0].getName() + "\n" +  author[0].getAge() + "\n" + author[0].getBooks());
console.log(author[1].getName() + "\n" +  author[1].getAge() + "\n" + author[1].getBooks());

Tags: , ,

2 Responses to “Inheritance in JavaScript”

  1. Shane says:

    I know it’s not really what this post is about, but I think your definition of a “scripting” language not being a programming language is a bit off.

    There are many languages that aren’t compiled before you run them, but they’re still “programming” languages. Like PHP and Python. A better way of saying what you want is saying that Javascript is an interpreted language, rather than a compiled one.

  2. M. says:

    @Shane Thanks for the comments. The point you raised about PHP being a ‘programming’ language although it isn’t compiled is actually a subject of much disagreement with some people, so I’ll leave it up to others to voice their opinions on that one.

    But I appreciate your clarification of the JavaScript language as an ‘interpreted’ language.

Leave a Reply