Stapes 0.7.0, and the end of create()
I’ve just released version 0.7.0 of Stapes.js, my MVC Javascript microframework. A big change in this release is the deprecation of the create
method and the introduction of the new subclass
method.
Why the change? The old system worked nicely for single modules, but was broken when trying to create an extension hierarchy. In the old system the creation of a class and the instantiation of that class were the same thing. In really simplified code that looked something like this:
(function() { | |
var Module = { | |
create : function() { | |
return Object.create(this); | |
} | |
}; | |
window.Stapes = { | |
create : function() { | |
return Object.create(Module); | |
} | |
}; | |
})(); | |
var Animal = Stapes.create(); | |
var Dog = Animal.create(); |
The main problem with this approach is that every property that has been added to Animal
after the initial create
will become part of the prototype of Dog
as well. Even if those properties are instance properties (e.g. Animal.bark = true
instead of Animal.prototype.bark = true
). This lead to difficult to detect bugs and behaviour.
So, i changed the API so you can create proper classes, based on the new Ecmascript Harmony classes spec. Those of you using Coffeescript or Livescript will feel right at home here.
var Module = Stapes.subclass({ | |
constructor : function(name) { | |
this.name = name; | |
}, | |
sayName : function() { | |
console.log(this.name); | |
} | |
}); | |
var module = new Module('Emmylou'); | |
module.sayName(); // 'Emmylou' |
constructor
will become the function that is being called when making an instance with new
. All other methods in the object will become part of the class prototype.
The new Module
is just a standard Javascript class, so you can add prototype properties using Module.prototype
or static properties using direct assignment. Stapes has two convenience methods for this called extend
and proto
that allow you to quickly add an object of properties to the prototype or directly to the module.
Inheritance can be done by simply calling subclass
on a newly created class. The instanceof
operator now works correctly too:
var Module = Stapes.subclass(); | |
var SubModule = Module.subclass(); | |
var module = new Module(); | |
var submodule = new SubModule(); | |
module instanceof Module; // true | |
submodule instanceof Module; // true | |
module instanceof SubModule; // false |
Every module now gets a parent
property, referencing the parent’s prototype. You can use this to still call a parent method if you’ve overwritten it.
var Module = Stapes.subclass({ | |
sayName : function() { | |
console.log('i say my name!'); | |
} | |
}); | |
var BetterModule = Module.subclass({ | |
// Note that this method name is the same as the one in Module | |
sayName : function() { | |
BetterModule.parent.sayName.apply(this, arguments); | |
console.log('i say my name better'); | |
} | |
}); | |
var module = new BetterModule(); | |
module.sayName(); // 'i say my name! i say my name better!' |
Note that for backwards compatibility the create
method on the Stapes
global will still work. However, because of the obvious problems it won’t work anymore on submodules. In the future i’ll remove Stapes.create
. If you like the old style i recommend you switch to something like var module = (Stapes.subclass()).extend()
which is more or less the same as the old Stapes.create().extend()
pattern.
So, that’s it. Please leave any questions and remarks in the question section below or file tickets on Github.
hrstuks
Hey, I really like Stapes. For some reason code view isn’t working?