I’ve Moved!

In order to demonstrate my code better I needed the ability to execute JavaScript on my pages and I wanted a simpler solution to offering source files than what Box.net offered.

I’m now over at http://blog.josh-davis.org.

You can get to this post on my new site at http://blog.josh-davis.org/2007/04/30/prototype-object-oriented-javascript/

Original Post

My earlier posts jumped right in with some somewhat advanced concepts of Object Oriented programming in JavaScript – specifically through the use of prototype. In this article I’m going to take a step back and explain prototype and how it fits into JavaScript OOP programming. This really just scratches the surface, but you need to start somewhere, right?

Prototype

Prototype is a built-in JavaScript object which is a child of all objects and is used to create properties and methods for all instances of an object. You can use it on your JavaScript objects to create classes with externally defined methods. My Event object uses this multiple times to add methods:

function Event()
{
    ...
}
Event.prototype.fireEvent = function(e,obj,evt,args)
{
    ...
};

You can also add methods to built-in JavaScript objects. An example of this is my bind method which is added to Function to allow all function objects to make use of it:

Function.prototype.bind = function (object)
{
    ...
};

Inheritance

You can also use prototype to create a class which extends another. For example if you have a class as such:

function Animal(legsIn)
{
    this.legs = legsIn;
};
Animal.prototype.getLegs()
{
    return this.legs;
};

var dog = new Animal(4);

This creates a very generic class called Animal which when the constructor is called sets the number of legs. I’ve created an instance of Animal called dog by calling new Animal(4). The new keyword indicates that you want to create a new instance of the class Animal by calling the function Animal as a class constructor. The return of a constructor is an instance of the object (which is implicit so you don’t have to include return this;). As part of the constructor call you will want to include any required arguments, in this case 4, which sets the Animal’s legs property to 4 by setting this.legs = legsIn. The this object is also a child of all objects and is used to indicate the object within it’s own context. Now when dog.getLegs() is called it will return 4.

If you want to extend this to get more specific you could create a new class:

function Bird()
{
    Animal.call(this,2);
    this.wings = 2;
};

Bird.prototype = new Animal();

Bird.prototype.getWings()
{
   return this.wings;
};

var penguin = new Bird();

The Animal.call(this,2) line uses the built-in JavaScript method call to call the Animal constructor in the context of Bird. The first argument of call is the context (this refers to the instance of Bird), while any further arguments refer to the arguments of the parent class (in this case I’m setting “legs” to 2 because birds have 2 legs). The Bird.prototype = new Animal() line is creating a subclass (Bird) of the parent (Animal).

Now if you call penguin.getLegs() you’ll get 2 and if you call penguin.getWings() you’ll get 2. This is because you’ve inherited the getLegs method from Animal and added a new method to Bird called getWings.

Polymorphism

Polymorphism is basically the ability of an object or method to act different in different contexts. For example, we could add a method to Animal:

Animal.prototype.swims = function()
{
    return "I swim...";
};

Let’s try two subclasses:

Otter.prototype.swims = function()
{
    var swims = Animal.prototype.swims.call(this);
    return swims + "like a fish";
};

var otter = new Otter(4);

Dodo.prototype.swims = function()
{
    var swims = Animal.prototype.swims.call(this);
    return swims + "like a rock";
};

var dodo = new Dodo(2);

Calling otter.swims() returns “I swim…like a fish” while calling dodo.swims() returns “I swim…like a rock”. The “I swim…” portion comes from the Animal class’s instance of swims and is retrieved through Animal.prototype.swims.call(this) which calls Animal.prototype.swims in the context of the child class.

Override

Alternatively you can override a parent’s methods by omitting the …call(this) portion of the method:

Dodo.prototype.swims = function()
{
    return "Are you crazy! Dodos can't swim.";
};

var dodo = new Dodo(2);

Now calling dodo.swims() returns “Are you crazy! Dodo’s can’t swim.” and does not call the Animal class’s version of swims at all.

4 Responses to “Prototype & Object Oriented JavaScript”

  1. luchkovsky Says:

    There is an approach to implement JavaScript prototype-based inheritance – a lazy inheritance which has all benefits of prototype-based inheritance, but also eliminates necessity to declare external scripts in proper order and automatically resolves and loads (if necessary) dependencies to external scripts that contains related classes.

    Only one line required to inherit Bird from Animal:

    function Bird()
    {
    // Calls lazy inheritance….
    var self = JSINER.extend(this, Animal);

    self.wings = 2;
    return self;
    }

    More about lazy inheritance on: http://ajaxline.com/lazy-inheritance


  2. [...] a recent blog post, Prototype & Object Oriented JavaScript, Josh Davis explains [...]

  3. ruchira Says:

    Thanks for the help

  4. AzamSharp Says:

    you have not showed how to call a prototype (javascript property)

    :(


Leave a Reply