PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Eight Weeks of Prototype: Week 6, Writing JavaScript Classes with Prototype

Inheritance

A child class is one that extends from another class, meaning the properties and methods of the parent class now also belong to the child. Additionally, the child class can overwrite any methods as it sees fit, or it can create its own methods that don't exist in the parent.

While JavaScript doesn't provide OOP features such as abstract classes or interfaces, Prototype does make it fairly straightforward to create child classes.

Note: Technically it's possible to emulate abstract classes by creating a method in the abstract class that throws an exception. This exception will not occur if the child class has its own implementation of the method.

To create a child class, you still use the Class.create() method, but rather than passing the class methods as the first argument, you pass them as the second argument, and instead you pass the name of the parent class as the first argument. This is demonstrated in Listing 6.

According to the naming rules mentioned earlier in the article, my preference is to call this class Person_Australian (since it becomes part of the Person package) and to save it in a directory called Person (./Person/Australian.js).

Listing 6 Creating a sub-class of Person (Australian.js)
var Person_Australian = Class.create(Person, {
    // all methods are inherited, more can be defined here
});

Because Prototype isn't really designed to have class inheritance, you must make the small concession of adding an extra parameter to each method you want to overwrite in child classes. This extra parameter is called $super and it is the first argument to the method. It is in fact a variable holding the parent method of the same name, meaning you can call $super().

Listings 7 and 8 demonstrate this by adding a method called getCountry() to the Person class. In the Person_Australian class we override this method so we can return the name of the country. As you can see, the method accepts $super as its first (and in this case, only) argument; however when you call this method you still don't use any arguments since Prototype internally passes the $super argument. This is demonstrated in Listing 9 which loads and instantiates the two classes.

Note: Since the declaration of the Person_Australian class relies on the Person class, you must be sure to load the Person.js file before Australian.js.
Listing 7 Declaring the parent getCountry() method (Person.js)
var Person = Class.create({
 
    name : null,
 
    initialize : function(name)
    {
        this.setName(name);
    },
 
    setName : function(name)
    {
        this.name = name;
    },
 
    getName : function()
    {
        return this.name;
    },
 
    getCountry : function()
    {
        return 'Unknown';
    }
});
Listing 8 Overriding getCountry() in the child class (Australian.js)
var Person_Australian = Class.create(Person, {
 
    getCountry : function($super)
    {
        return 'Australia, not ' + $super();
    }
});
Listing 9 Loading and instantiating the Person and Person_Australian classes (listing-9.html)
<html>
    <head>
        <title>Loading and instantiating the Person and Person_Australian classes</title>
        <script type="text/javascript" src="/js/prototype.js"></script>
        <script type="text/javascript" src="/js/Person.js"></script>
        <script type="text/javascript" src="/js/Person/Australian.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            var you = new Person('Some Person');
            alert(you.getCountry());
            // displays "Unknown"
 
            var me = new Person_Australian('Quentin Zervaas');
            alert(me.getCountry());
            // displays "Australia, not Unknown"
        </script>
    </body>
</html>

In This Article