Now that’s class, it’s an object! – Prototypal Inheritance in JavaScript

JavaScript is an object oriented programming language like most programming languages nowadays. However, unlike most programming languages it does not use the concept of classes. Instead from classes objects inherit directly from other objects, their so called prototypes. If you’re familiar with a traditional object oriented programming language like Java or C++ and / or if you already have fundamental knowledge of JavaScript, then this article is directed at you.

In the beginning there was Object.prototype

To fully understand how object oriented JavaScript works, you will have to abandon any concept of object orientation you know. Yes, forget it. You won’t need it, and I will teach you anew. JavaScript object orientation works quite differently than in most other languages, you will only get confused about what is going on in JavaScript if you try to apply your old concepts and ideas of object orientation to JavaScript. So forget about it. Done? Good. So now that you forgot, let me introduce you to the object:

{};

This is what we call an object literal in JavaScript. It is the most basic form of an object and works similar to array literals in other languages. You may have noticed that there is no reference to a class. – Didn’t I tell you to forget everything you know about other object oriented languages?! That certainly includes classes! – Whatever, there are no classes in JavaScript. Objects in JavaScript do not inherit from classes, but from other objects, their so called prototypes. If an object does not have an explicit prototype, like in the case of an object literal, it will inherit from a special built-in object, which is accessible through Object.prototype.

Objects in JavaScript are dynamic hashmaps. A hashmap is a set of key/value pairs. For each value in an object, like an attribute or a method, there is a key, that identifies that value and allows access to it. You can access an object member with the dot operator followed by the literal key (dot notation) or by enclosing the key in string form in index brackets (bracket notation):

o.member; // dot notation
o['member']; // bracket notation

If you think the bracket notation looks a lot like accessing arrays then this is because arrays in JavaScript basically are nothing but objects with integer attribute keys.

Because objects are dynamic, you can add and remove any member at runtime, even after the object was created. You add a member by simply assigning to it and your remove it by using the delete operator on the member:

var o = {}; // create an empty object
o.member = 'value'; // create the attribute "member" by assigning 
                    // value "value" to it
o.method = function() { // create the method "method" by assigning 
                        // an anonymous function to it
  return this.member;
};
o.method(); // returns "value"
delete o.member; // delete the member "member"
o.method(); // returns undefined

Also, when you create an object using an object literal, you can add an arbitrary amount of attributes and methods to it, by listing key/value pairs, separated by comma and split by a colon:

var printer = {
  message: 'Hello, World!',
  count: 0,
  printMessage: function () {
    console.log(this.message);
    return ++this.count;
  }
};

Defining objects this way is very cool and singlehandedly eliminates the need for the singleton pattern, but it can be very tyring if you require multiple objects with the same attributes over and over again. What you want is a method that makes creating similar objects easy. Luckily JavaScript provides such a method.

Crock’ the Constructor

For easier object instantiation JavaScript provides the new keyword. Calling any function with a prepended new keyword will turn this function into a constructor function. Constructor functions basically work like normal functions with the difference that their this keyword will be bound to a newly created object and they will automatically return this newly created object if there is no explicit return statement. Although you could turn any arbitrary function into a constructor function using the new keyword, this does not make much sense in most cases. Usually you build special functions that will be used exclusively as constructor functions. By convention those functions start with a capital letter.

function Printer() {
  this.message = 'Hello, World!';
  this.count = 0;
  this.printMessage = function () {
    console.log(this.message);
    return ++this.count;
  };
}
var printer = new Printer();
printer.printMessage(); // prints "Hello, World!" to console
printer.count; // returns 1

What this constructor function does is implicitly create a new object and bind it to the functions this identifier. Then the function body is executed, which will create a message attribute, a count attribute and a printMessage method on the new object. Since there is no explicit return statement, the new object, augmented with it’s new members, will be returned implicitly.
Note though, that this construct is not a class. There are no classes is JavaScript. This is simply a function which adds members to a new object. The style of calling it might look a bit like a class constructor in other languages, but I told you: forget about what other languages do.

But there is a problem with this example. Not with constructor functions in general, but because we used a very naive variant. Each time we call this constructor function it will create a new object with a message and a count attribute. Up until here this is fine, but it will also create a new anonymous function and add it as a method to the object each time you call the constructor function. This means, that each object will get it’s own, separate function, which will require it’s own memory, it’s own compilation time, etc. While this >might> be what you want, it’s most likely not. What you actually want are several objects that all use the exact same function. Prototypes are what enables this in a very easy way.

Honor, guide me!

Prototypes are JavaScript’s way of inheritance. Each object in JavaScript has exactly one prototype. There are several ways to declare a newly created object’s prototype (and some implementations even allow the prototype to be changed after object instantiation), but let us look at how exactly prototypes work first.

When you read a member from an object, JavaScript will look for this member on the object itself first. If JavaScript cannot find the member on the object, it will go to the objects prototype and see if it can find the member there. If it fails again it will proceed to move along the prototype chain until it either finds the member on one of the prototype objects, in which case it will return it’s value or has reached the end of the chain without finding the member on any of the objects on the prototype chain. In that case undefined is returned.

If you write an object’s member by assigning to it, JavaScript will always set the objects own member. When assigning a member, JavaScript will never alter any object on the prototype chain. This is possible however, you will only need to do it explicitly. The following code will demonstrate what I just explained. Note that p is set as o‘s prototype.

var p = {
    key: 'value',
    method: function () {
      return this.key;
    }
  }, o = Object.create(p); // create an object with p as it's prototype
 
p.key; // returns 'value'
p.method(); // returns 'value'
 
o.key; // returns 'value'
o.method(); // calling a method is a read, returns 'value'
 
o.key = 'other'; // assign as o's own member!
o.key; // returns 'other'
p.key; // returns 'value'
 
o.method() // returns 'other', because the method
           // is evaluated with o bound to this, even
           // though the method actually is on p
 
delete o.key;
o.key; // returns 'value', after deletion the member
       // is no longer found on o, but still on p, when
       // traversing the prototype chain.
 
p.key = 'changed';
o.key; // returns 'changed', the prototype chain is
       // evaluated each time a property is read from.

I just introduced you to the first method of setting an objects prototype: Object.create(prototype);. Object.create returns an empty object with it’s prototype set to whatever object you pass in. Object.create can do more, but this is out of scope for this article.

When using an object literal you cannot specify a prototype for your object. The syntax simply doesn’t give you the tools to do so (although this might come in a future ECMAScript version). However, when using the constructor function pattern, you can specifiy the prototype of the created object. This is done by setting the prototype attribute of the constructor function. Whenever the function is called using the new keyword, the returned object will have it’s prototype set to whatever the value of the constructor functions prototype attribute was at the time:

var p = {
  key: 'value',
  method: function() {
    return this.key;
  }
};
function Thing() {
  // do nothing, implicitly return this
}
 
Thing.prototype = p; // make p the prototype of all objects created using Thing
Thing.prototype.constructor = Thing; // this is not required, but makes your 
                                     // objects pass the object.constructor 
                                     // === Thing test like you would expect.
 
var o = new Thing();
 
o.key; // returns 'value'
o.method(); // returns 'value'
 
p.key = 'changed'; // assign to the prototype
o.key; // returns 'changed'
 
o.key = 'other'; // assign o's own attribute
o.key; // retutns 'other'
 
// etc

With this pattern, you can now create an arbitrary amount of Things, which all inherit from p. All those Things share the exact same methods and attributes. Whenever you call a Things method method, it will call the exact same function p.method (that is as long as you do not explicitly set the Things members to something else). So in comparison to our first try with using the constructor function, we will save memory, compilation time, etc, because method exists only once, on the prototype p.

Busfactor

You now basically know everything you need to know about object oriented JavaScript. The rest is forging this knowledge into practically usable patterns. The following code is a small example how an object oriented system could be created using JavaScript prototypal inheritance. Be aware, that there are multiple patterns to do object orientation in JavaScript. Some embrace the prototypal nature of JavaScript, while others try to mimic what JavaScript people call classical object orientation.

Personally I don’t like classical patterns as much (especially those that try to mimic information hiding and private methods and attributes), since most will make your code slow and clunky. The following pattern is a good balance I think. It is aware of JavaScripts prototypal model, but people coming from a classical model will be able to grasp what it does.

function Vehicle() {
    this.passengers = 0;
}
 
Vehicle.prototype.seats = 0;
 
Vehicle.prototype.board = function() {
  if (this.seats > this.passengers) {
    this.passengers++;
  }
}
 
Vehicle.prototype.deboard = function() {
  if (this.passengers > 0) {
    this.passengers--;
  }
}
 
function Car() {
  Vehicle.apply(this, arguments);
}
 
Car.prototype = new Vehicle();
Car.prototype.constructor = Car;
Car.prototype.seats = 5;
 
function Bus(driver) {
  Vehicle.apply(this, arguments);
  this.driver = driver;
}
 
Bus.prototype = new Vehicle();
Bus.prototype.constructor = Bus;
Bus.prototype.seats = 20;
 
Bus.prototype.board = function (ticket) {
  if (ticket) {
    Vehicle.prototype.board.apply(this, arguments);
  }
}

JavaScript is all about functions and objects. That’s all what’s to it, even in it’s inheritance model. I hope you enjoyed this article. If you have any further questions or would like to comment, please do so below. If you want to learn more about JavaScript come back soon, to learn more about the secrets of closures, scope and functions. You can also subscribe to the feed, to stay tuned. Or, if you are in a hurry and want some good lecture, you should definitly check out Douglas Crockfords “JavaScript: The Good Parts” (Amazon Affiliate Link).

6 thoughts on “Now that’s class, it’s an object! – Prototypal Inheritance in JavaScript

  1. Pingback: JavaScript: Putting the fun into functions | blinzeln

  2. hi, thanks for the article. i saw your comment on stackoverflow and had a read through it.

    nevertheless i still have a few questions. i am writing my own ajax handler with iframes and its possible that two ajax requests may happen almost simultaneously (since ajax can be initiated by onclick events). i want to make sure that the data from the second instance of the iframe function constructor does not override the data of the first instance iframe function constructor. its probably easier to talk about the code so here it is: (sorry its quite long)

    window.onload = function(){
    document.getElementById(‘button1′).onclick = function(e){ajax_send(‘doc1.json’, ‘callback1′);};
    document.getElementById(‘button2′).onclick = function(e){ajax_send(‘doc2.json’, ‘callback2′);};
    };
    function ajax_send(ajax_url, ajax_callback_name){
    var ajax_new_iframe = document.createElement(‘iframe’);
    ajax_new_iframe.style.display = ‘none’;
    if(ajax_new_iframe.addEventListener) ajax_new_iframe.addEventListener(‘load’, ajax_receive, false);
    else if(ajax_new_iframe.attachEvent) ajax_new_iframe.attachEvent(‘onload’, ajax_receive);
    ajax_new_iframe.setAttribute(‘ajax_callback_function’, ajax_callback_name);
    ajax_new_iframe.setAttribute(‘src’, ajax_url);
    document.body.appendChild(ajax_new_iframe);
    };
    function ajax_receive(){
    var ajax_callback_function = window.this.getAttribute(‘ajax_callback_function’);
    var ajax_iframe_innerhtml = this.contentWindow.document.body.innerHTML;
    document.body.removeChild(this);
    if(typeof ajax_callback_function === ‘function’) ajax_callback_function(ajax_iframe_innerhtml);
    };

    so, assume that button1 and button2 are pressed almost at the same time. the main question i have is – will the event handler create a new instance of function ‘ajax_send’ for each button click or will they both refer to the same instance? and likewise, will the addEventListener/attachEvent functions refer to different instances of ajax_receive or will they both refer to the same instance? obviously my main concern is to prevent variables like ‘ajax_callback_function’ and ‘ajax_new_iframe’ from being overridden by the second button click.

    • They will refer to the same instance of those functions. This however will not produce the problem you are fearing. Each call to a function will create it’s own context. Another call to the same function will not interfer with that context. Also, since JavaScript is does not provide threads, nothing ever happens in parallel. That means that when ajax_send is called it will always return, before any other event has the chance to call it. Hope this helped.

      • cheers for the reply mate and sorry for the delay in my reply – i’ve been on annual leave and just got back. so just to clarify – are you sure about the ajax_send function completely executing and returning before the second event is allowed to start executing the ajax_send function? that would be very handy if it is true but i haven’t been able to find any references to that behaviour on google. do you know of any references or maybe a simple test that i can run in firebug to view this behaviour?

        thanks again!
        peter

        • actually i can answer my own question. this link explains it: http://javascript.info/tutorial/events-and-timing-depth

          “The browser has inner loop, called Event Loop, which checks the queue and processes events, executes functions etc.

          For example, if the browser is busy processing your onclick, and another event happened in the background (like script onload), it appends to the queue. When the onclick handler is complete, the queue is checked and the script is executed.

          setTimeout/setInterval also put executions of their functions into the event queue if browser is busy.

          In fact, most interactions and activities get passed through the Event Loop.”

          so i can safely assume that javascript’s single thread will not allow the program flow to enter the send_ajax function until the first event has been finished :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>