Helma Logo
main list history
previous version  overview  next version

Version 5 by Lehni on 05. September 2006, 09:10

*This post|http://helma.org/pipermail/helma-dev/2006-July/002941.html* about Dean Edward's *Base Class for JavaScript Inheritance|http://dean.edwards.name/weblog/2006/03/base/* started the discussion about JavaScript OOP in Helma.

Hannes came up with *his own impementation|JavaScript Inheritance Sugar*, and in parallel, without realizing this, I was following the discussion on Dean's page and found *Ben Newman's implementation|http://seraph.im/* for Prototype, which looked very clean and which I used as a base for my own improvements (described in *this post|http://helma.org/pipermail/helma-dev/2006-August/003057.html*):

* The use of this.$super() instead of this.sup() (Hannes named it the same, and this is a pure coincidence)
* Code that checks if $super is actually in use, and only wraps the function if it does use $super.
* The addition of Class.inject, that allows the modification of the class at runtime (adding of new methods and overriding existing ones by inheriting from itself).

I then finally came across Hannes' implementation and realized it is solving some problems in a much cleaner way: For example it does not copy over methods from base class, but creates a proper inheritance chain using prototypes, also, the code was more readable, but also longer.

I started to combine both efforts into one library and address some more issues. The result is very tight and offers a lot of functionality. I am pretty happy with it and would like to share it here. Here a short description of its features, bellow the actual code.

__Description__

Classes are defined by using Object.extend. The function takes two hash-lists (JS Objects), the first one for the instance fields, the second one for static class fields. Inheritance is implemented for both, so static class methods can be inherited from base classes and called through $super too. Each class that is created in such a way recieved the static functions "extend" and "inject". extend does the same as Object.extend, .inject works similarly, but instead of creating a new class, in simply adds the fields to the existing class, so modification of classes at runtime is possible. If a function is overriden in such a way, $super can be used to call the previous definition of that function before the call to inject.

A change was made to not "hardcode" the function if $super is used, but to look it up each time instead. Before, changes to the $super method after inheritance where not reflected in the function that inherited from the super class.

Examples:

var One = Object.extend({ // instance fields
test: function() {
alert("One");
}
}, { // class fields
test: function() {
alert('Static One');
},
 
// define a constant
PI: Math.PI
});
 
var Two = One.extend({
test: function() {
this.$super();
alert("Two");
}
}, {
test: function() {
this.$super();
alert('Static Two');
}
});

var o = new Two();

o.test(); // One - Two

// now modify the function directly:
One.prototype.test = function() { alert("Eins"); }

o.test(); // Eins - Two: the change was reflect in the call to $super

// The same happens with static class functions:

Two.test(); // Static One - Static Two

// now modify the static function directly:
One.test = function() { alert("Statisch Eins"); }

Two.test(); // Statisch Eins - Static Two: the change was reflect in the call to $super

// Note that not only functions are inherited:
alert(Two.PI);

     removed
     added