Prototype: add methods to a class

Prototype is surely among my favorite libraries when it comes to OOP. To be honest, Prototype provides many methods for handling OOP, more than jQuery. One of its best features is the addMethods() method of the Class interface. The fact is that Prototype implements natively most of the well-known JavaScript design patterns used to create objects, so many of its methods use these patterns under the hood. This method features the following:

New methods propagate down the inheritance chain. If the class has subclasses, those subclasses will receive the new methods — even in the context of $super calls. The new methods also propagate to instances of the class and of all its subclasses, even those that have already been instantiated.

The example provided with the documentation creates two objects:

var Animal = Class.create({
  initialize: function(name, sound) {
    this.name  = name;
    this.sound = sound;
  },
 
  speak: function() {
    alert(this.name + " says: " + this.sound + "!");
  }
});
 
// subclassing Animal
var Snake = Class.create(Animal, {
  initialize: function($super, name) {
    $super(name, 'hissssssssss');
  }
});
 
var ringneck = new Snake("Ringneck", "hissssssss");
ringneck.speak();
 
//-> alerts "Ringneck says: hissssssss!"

$super is the Prototype's way to access the parent class/object in order to get all of its methods and properties. This keyword / method is passed as the first argument of the initialize() method. Many of you may have noticed that the name of this keyword / method is the same of a popular pattern created by Douglas Crockford. This is not accidental.

The addMethods() is used as follows:

// adding Snake#speak (with a supercall)
Snake.addMethods({
  speak: function($super) {
    $super();
    alert("You should probably run. He looks really mad.");
  }
});

By using $super(), the redefined method has access to the original parent's method, so the original value returned by the speak() method is not overridden:

ringneck.speak();
//-> alerts "Ringneck says: hissssssss!"
//-> alerts "You should probably run. He looks really mad."

If you want to override the original method, you can do the following:

// redefining Animal#speak
Animal.addMethods({
  speak: function() {
    alert(this.name + 'snarls: ' + this.sound + '!');
  }
});
 
ringneck.speak();
//-> alerts "Ringneck snarls: hissssssss!"
//-> alerts "You should probably run. He looks really mad."

Leave a Reply

Note: Only a member of this blog may post a comment.