Object oriented javascript with Mootools

We’ve seen a lot of talk lately about OO javascript. I won’t come back on that as there’s many tutorial and blog posts about it. However, I rarely seen articles about the OO capabilities of Mootools. While every Mootools users are probably aware about it ,Mootools is not the most used framework, and not all javascript developers may now its great features in that field.

Mootools introduces the Class object which allows you to, obviously, create classes. To create a class, you need to create a new instance of this object. Beware that we define the class here, even if we’re using the new keyword. The Class’s constructor takes as argument an object defining methods and properties.

var MyFirstClass = new Class({
    message: "hello world",
    sayHello: function() {
        alert(this.message);
    }
});

As you can see, we can use the this keyword to reference the instance. Creating an instance of the class is straightforward:

var obj = new MyFirstClass();
obj.sayHello();

While this should seems pretty “standard” for any OO developer, it is not for javascript. The protoype (not the framework) way of doing things, while powerful, is quite awkward! And as we’re going to see, Mootools offers much more regarding OO features.

If you’re class needs a constructor, you can define a method named initialize

var HelloWord = new Class({
    initialize: function(name) {
        alert('hello ' + name);
    }
});

new HelloWorld('peter');

Classes can of course extend each other. Mootools supports only one parent class. It can be defined by adding a property named Extends to your class definition. The property’s value must be an object.

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

var Human = new Class({
    Extends: Animal,
    speak: function() {
        alert(this.name + 'said bla bla bla');
    }
});

var peter = new Human('peter');
peter.eat();
peter.speak();

When subclassing, a method (not only the constructor) can call the same method from its parent class using the this.parent() function.

var Peter = new Class({
    Extends: Human,
    initialize: function() {
        this.parent('peter');
    }
});

Class can also use the special Implements property. Do not confuse this with the java or php implements keyword as it does not have the same behavior. In Mootools classes, Implements will merge properties from one or many objects into your class, overriding any method with the same name. It is useful to implement extra class features.

Indeed, Mootools comes with three extra class features: Chain, Events and Options. They can be added to your class using the Implements properties.

var MyClass = new Class({ Implements: [Chain, Events] });

Events adds events support with common methods like addEvent(), removeEvent() … It also adds the fireEvent() method which, as its name implies, fires an event.

var Paul = new Class({
    Extends: Human
    Implements: Events,
    initialize: function() {
        this.parent('paul');
    },
    speak: function() {
        this.parent();
        this.fireEvent('speaking');
    }
});

var paul = new Paul();
paul.addEvent('speaking', function() { /* ... */ });

The Chain and Options feature are also pretty neat but I let you check the Mootools documentation on these one.

I’ve gone through the documented features and we’ll now see some less known ones. For example, adding static properties (even if it seems pretty obvious).

var MyClass = new Class({ /* ... */ });
MyClass.staticProperty = '';
MyClass.staticMethod = function() {};

Don’t forget to use the class name when calling them (you can’t use the this keyword). A common design pattern in OO is Singleton. This can easily be implemented using a closure.

var MyClass = (function() {
    var MyClassSingleton = new Class({ /* ... */ });
    var instance;
    return function() {
        return instance ? instance : instance = new MyClassSingleton();
    }
})();

var obj1 = new MyClass();
var obj2 = new MyClass(); // same instance, obj1 == obj2

The Extends and Implements properties are called mutators and you can define you’re own ones. This can be done by adding a property to the Class.Mutators object named after your special property. This property should be a function with two parameters: the first one will be an object with the class properties and the second one the value of the mutator property. The function must return an object with the class properties.

Class.Mutators.MyMutator = function(properties, mutatorValue) { /* ... */ };
var MyClass = new Class({ MyMutator: "mutator value" });

I hope I covered most of what is to know about Mootools and classes. I’ll soon, probably tomorrow, write an article about javascript and namespaces using a custom library I made.



comments powered by Disqus

11/02/2009