A Quick and Easy JavaScript Inheritance Tutorial

JavaScript is not a class-based object oriented programming language and thus has no concept of a class, unlike languages like C++ and Java that use classical inheritance. Rather it uses prototypal inheritance - every object inherits from some other object through a concept known as the prototype chain.

Everything is an object

Well, not everything.

Operators like + and % aren’t objects.

literal such as "Howdy" isn’t technically an object, but if a variable str that is assigned the value "Howdy" calls one of the String object’s methods – e.g. charAt - then str is temporarily converted to an instance of String for as long as it takes to execute the function code.

The same goes for numbers like 123 and arrays like [ "a", "b", "c" ].

Any function inherits from the Function object which itself inherits from the Object object. In fact, Object is essentially the mother of all objects since most everything either inherits from Object directly or inherits from StringNumberArrayBoolean, or any of the other “base” objects (DateMathRegExp, and Global are in there, too) which themselves all inherit from Object in one glorious circle of life.

Creating objects

There are two ways to create new objects in JavaScript. The first is to define an object literal which is a collection of name-value pairs separated by commas and encased in curly braces.

var pet = {
    name: "Fido",
    species: "dog",
    bark: function () {
        alert("WOOF!");
    }
};

These don’t have an explicit prototype property, but inherit “under the hood” from Object's prototype (Webkit and Mozilla browsers allow you to view an object literal’s prototype via the __proto__ property which is unavailable in Internet Explorer).

The other way to create an object is to define a constructor function that when invoked creates an object.

var Person = function (name) {
    this.name = name;
};
var me = new Person("Nathaniel");

The variable me is assigned an object with only one property - name has the value "Nathaniel" - plus an “under the hood” reference to a prototype object which stores a reference to the constructor as well as a pointer to Object's prototype from which it inherits. As alluded to above the “under the hood” prototype reference is exposed in Webkit and Mozilla browsers as __proto__.

Prototypes

So what happens when you modify Person's prototype?

var Person = function (name) {
    this.name = name;
};
Person.prototype.greet = function () {
    alert("Hello! My name is " + this.name + ".");
};
var me = new Person("Nathaniel");

me itself remains the same with just the one name property, but __proto__ now contains a method greet. Properties and methods defined on a constructor’s prototype are available to all instances by reference, and don’t contribute to instantiation overhead.

And since the greet method is part of the prototype, which is associated to instances by reference, every instance of Person points to the same definition which itself references the name property of the specific instance.

var you = new Person("Joe Sixpack");
var her = new Person("Jennifer");

me.greet(); // Alerts "Hello! My name is Nathaniel."
you.greet(); // Alerts "Hello! My name is Joe Sixpack."
her.greet(); // Alerts "Hello! My name is Jennifer."

That’s all obvious, but it’s important to note that you can also do the following:

Person.prototype.greet = function () {
    alert("Howdy, neighbor!");
};

me.greet(); // Alerts "Howdy, neighbor!"
you.greet(); // Alerts "Howdy, neighbor!"
her.greet(); // Alerts "Howdy, neighbor!"

If you change the value of any member of a constructor’s prototype all instances both existing and future recognize the change, effective immediately.

Setting up inheritance between two objects

Let’s say we want to create a new “class” object Employee that inherits from Person but has its own specialized properties or methods. First things first, let’s create the Employee constructor:

var Employee = function (name, company, title) {
    this.name = name;
    this.company = company;
    this.title = title;
};

In order to set up inheritance between Employee and Person we need to assign Person as the prototype of Employee. There are two ways to do this.

Employee.prototype = new Person();
Employee.prototype.constructor = Employee;

The first line of code establishes that Employee's prototype should essentially be an instance of Person and thus have access to all of Person's prototype members just as any instance would. JavaScript by default assigns Person to the constructor property of Employee's prototype, however, so the second line is needed to reset Employee's constructor to Employee.

There’s a slight problem here, though, that isn’t evident in our specific example involving PersonPerson's constructor is a function like any other function capable of running whatever code we feel like including. For example, let’s say Person's constructor looked like this instead of the above example:

var Person = function (name) {
    this.name = name;
    $("body").append('<p>New person added: ' + this.name);
};

This probably isn’t a realistic example, but the point is that the constructor function can run any code including other functions that we may not want to execute if we’re not creating a straight up instance of Person. We want to be able to grab Person's prototype without actually invoking its constructor. To do this we use a second similar technique.

var proxy = function () {};
proxy.prototype = Person.prototype;
Employee.prototype = new proxy();
Employee.prototype.constructor = Employee;

Since we don’t want to invoke Person's constructor we instead use a dummy function as a replacement constructor to instantiate as Employee's prototype. The end result is the same since Employee doesn’t care about anything in Person's constructor – it only wants to know what it should inherit through the prototype.

We still need to reset the constructor property of Employee's prototype which points to Person since it’s inherited from Person.

In either case we end up with an Employee object whose instances have a different set of constructed properties than instances of Person but have access to the greet method from Person's prototype.

Keep in mind, though, that said access to greet is still association by reference so if you change the value of greet in Person's prototype than any instance of Employee will reflect that change going forward.

The prototype chain

As objects inherit from one another they form what is popularly described as a prototype chain along which the JavaScript engine can search for a called property or method.

var e = new Employee("Steve Jobs", "Apple", "CEO");
alert(e.toString()); // Alerts "[object Object]"

When we invoke e.toString JavaScript first looks at the instance itself to see if it has a property or method of that name. Not finding such a member, JavaScript then looks at the instance’s prototype, which refers to Person's prototype, to see if there’s a toString property or method defined there. Since Person's prototype doesn’t include toString, JavaScript then has to go up the prototype chain to the next link, which happens to be the Object object. That prototype does contain a toString method which gets invoked and alerts the string representation of the object.

Only after JavaScript fails to find the property or method in question anywhere on the prototype chain does it give the undefined notification.

Use Prototypes… and I Don’t Mean the Framework

I’m quite surprised at the number of developers I’ve worked with who have a working knowledge of JavaScript but don’t know how JavaScript prototypes work.

Of all the accomplished software engineers I’ve had the privilege of working with only two had even heard of the concept, and one of those guys is pretty close to brilliant having done crazy things like implementing Self in JavaScript!

About a month after I started working at my current place of employment, I was assigned the task of developing a new version of one of our widgets which included a number of “panels” that users would interact with to accomplish their goal. Different panels could have different types of functionality so an obvious starting point was to create a basic “Panel” object from which other types of panels would inherit, and this in fact was one of the project requirements provided to me by the engineering manager.

During the first code review involving yours truly and that manager, it became very clear within moments that he had absolutely no idea what JavaScript prototypes were and had never seen JavaScript’s native inheritance in action. His only experience with “prototype” in the context of JavaScript was with the Prototype framework he used for client-side coding.

This is a software engineer who, while spending most of his time on the server side working with languages like Ruby that use the classical inheritance paradigm, was solely responsible for all of the JavaScript programming for the application with the most complex user interactions!

I tried to explain how prototypal inheritance worked in JavaScript, but I might as well have been speaking a foreign language – he just couldn’t wrap his head around the concept (granted, this was during the span of the one hour during which the code review session took place).

His first reaction was to ask me to consider implementing a more classical inheritance approach in JavaScript in case he or other engineers on the team had to work with my code. This would have sparked a brief debate on the merits of emulating classical inheritance when a perfectly good native inheritance scheme is available, but he was called into an emergency meeting and the subject never came up again since I took over pretty much all major JavaScript development for the company.

While I can understand where my manager was coming from I really didn’t see much point in reinventing the wheel. JavaScript tackles the issue of object inheritance in a clean and easy way with its prototype paradigm, and while a number of JavaScript gurus such as Douglas CrockfordJohn Resig and Dean Edwards have served up their own solutions as to how to emulate the classical inheritance methodology as seen in Java, C++ and other class-based languages, any one of them will likely tell you that in most scenarios prototypical inheritance is the way to go in JavaScript: you won’t have to invest resources in writing the emulators and any new JavaScript programmer added to the team can hit the ground running with the functionality inherent to the language.