Creating classes

Classes are the basic building blocks of many object-oriented systems. JavaScript 1.x (a.k.a. ECMAScript 3) does not support classes natively, although it has prototype objects and constructor functions that look a lot like classes in terms of syntax. Creating class-based programs in JavaScript can be cumbersome, but jsclass makes it easier.

// In the browser
JS.require('JS.Class', function(Class) { ... });

// In CommonJS
var Class = require('jsclass/src/core').Class;

To make a class, you just ask for a new Class(), and list the names of the methods the class has as regular JavaScript functions.

var Animal = new Class({
    initialize: function(name) {
        this.name = name;
    },

    speak: function(things) {
        return 'My name is ' + this.name + ' and I like ' + things;
    }
});

Classes are expected to have an initialize() method, though this is not essential if no parameters are used to construct instances. The initialize() method is called when you make an instance of the class, and is passed the parameters used to instantiate the new object.

var nemo = new Animal('Nemo');    // nemo.name == "Nemo" 

nemo.speak('swimming')
// -> "My name is Nemo and I like swimming"

Inheriting from a parent class

Let’s say we want to model a more specific kind of animal. We can create a class Dog as follows:

var Dog = new Class(Animal, {
    speak: function(stuff) {
        return this.callSuper().toUpperCase() + '!';
    },

    huntForBones: function(garden) {
        // ...
    }
});

Dog does not need its own initialize() method as it inherits one from Animal. However, it chooses to override the speak() method with its own version.

Now we come to a special method generated by jsclass, called callSuper(). This method gets created dynamically inside method calls and allows you to access the current method in the parent class. Similar to Ruby, you don’t have to pass any arguments to callSuper(), thus avoiding repetition. The arguments given to the current method are automatically passed by callSuper() up to the parent method.

var rex = new Dog('Rex');
rex.speak('barking')
// -> "MY NAME IS REX AND I LIKE BARKING!"

callSuper() only exists while there are super-calling methods on the stack, and only if there is an actual super method to dispatch to. If there are no inherited methods to call, the callSuper is undefined.

rex.callSuper();
// -> rex.callSuper is not a function

You can pass arguments to callSuper() to override the ones passed in automatically, e.g.:

var Dog = new Class(Animal, {
    speak: function(stuff) {
        stuff = stuff.replace(/[aeiou]/ig, '_');
        return this.callSuper(stuff).toUpperCase() + '!';
    }
});

var rex = new Dog('rex');
rex.speak('something')
// -> "MY NAME IS REX AND I LIKE S_M_TH_NG!"

When overriding arguments you should note that callSuper() always passes all the current method’s arguments, minus the specifically overridden ones. So if you have a method that takes arguments A, B, C, D, and E and inside that method you call

this.callSuper('one', 'two')

then the code that actually runs is

this.callSuper('one', 'two', C, D, E)

Ruby’s inheritance system is more powerful than simply calling methods in parent classes. For more information on how it works, refer to the inheritance article.