Inheritance in Backbone
Backbone.js comes with a minimalist OO inheritance framework similar to the one employed by CoffeeScript. Each base class has a static method called extend
that is used to create a subclass, like this:
User = Backbone.Model.extend({
// instance methods
},
{
// class methods
});
extend
returns a constructor whose prototype inherits from Backbone.Model.prototype. References to all of Backbone.Model’s static methods and properties (including extend
) are copied to the new constructor.
Calling ‘super’
The constructor also receives a __super__
property, which references its superclass.
User.__super__ === Backbone.Model.prototype
This makes it possible to call super
inside of a class or and instance method:
User.prototype.save = function(attrs) {
this.beforeSave(attrs);
User.__super__.save.apply(this, arguments);
};
CoffeeScript has a super
keyword that compiles to the line above, but when using Backbone with plain javascript, its a little grating to have to type that out.
A small layer of convenience
I wrote this little super
method (test-driven using jasmine) which saves me having to repeat the constructor’s name all over the place. You call it like this:
User.prototype.save = function(attrs) {
this.beforeSave(attrs);
this._super("save", arguments);
};
The second parameter to _super
is the array of arguments to pass to the overridden method. This is to optimize for the common case of passing the arguments
object straight through.
There’s no way to avoid having to repeat the method name like that, unless you wrap every method definition with a helper function that either passes the overridden method as a parameter (a la Prototype.js) or reassigns a hidden super
property behind the scenes (like JS.Class or John Resig’s approach). These approaches won’t work with Backbone’s ultra-minimalist inheritance system.
About the Author