MooTools Class Mutators

Thursday, December 11th, 2008 @ 4:19 pm | filed under: Your Questions

This question got posted to the MooTools User Group earlier and I thought I’d answer it here because it’s pretty interesting:

Hey everyone,

I just discovered Mutators today when I was digging through the mootools source. I’ve been using mootools for a couple of years now and am pretty familiar with some of it’s internals. Coming from a heavy OOP background I found the whole extending and implementing classes in JS very interesting. So, what I’m really wondering is this:

What is the formal definition of Mutators?

What are the pros and cons of developing them to add features to JS classes?

Thanks,
Brandon

Mutators take properties of classes and process them in specific ways. MooTools only ships with the two: Extends and Implements. It’s important to note that mutators are applied to the class when you invoke new Class, so they can only be used to alter classes themselves, not instances of them. So, for instance, Extends is processed when you do this:

var Widget = new Class({
Extends: Foo,
initialize: function(){ ...}
});

Extends creates a new instance of Foo and mixes it in to Widget. Unlike the initialize method, which is used when you invoke new Widget.

In general, mutators are useful when you want to run functionality when classes are created, but not when they are instantiated. This low level access lets you change the way classes themselves work, but only in this very specific way. The only mutator that I’ve ever actually found a user for was the Class.Binds mutator (which I originally got from Jan), which let you do this:

var Widget = new Class({
binds: ['click'],
initialize: function(el) {
el.addEvent('click', this.click);
},
click: function(){
console.log(this);
}
});

Normally the console statement above would log el because this by default points to the element unless you use Function.bind to make sure the method is bound to your instance of the class.

The Class.Binds mutator let you specify a property (binds) that listed the names of methods that should automatically be bound to the instance of the class.

MooTools 1.2 reworked how classes work a bit (mostly to work around Opera bugs and the like). Consequently mutators like Class.Binds won’t work, because they need to be applied when you invoke the class (new Widget) in order to bind them to that instance. I have a Class.Binds replacement that runs at runtime that almost duplicates this entirely (you have to call a method to bind the classes).

MooTools 1.3 should include a post-instantiation mutator that will let me make Class.Binds work the way it used to (i.e. invoke a method when the class instance is created).

The only other mutators that I’m aware of were authored by Nathan White that were designed to create Singletons and to help with the creation of private methods through closures.

Update: Nathan points out that there’s also an Exposes mutator that Jan put together.

Comments are closed.