If you’ve ever done a lot of JS development you might find the following situation familiar: you’re loath to open up the bowels of the sweet webapp you wrote because you know inside you will find hundreds of lines of jQuery selectors stacked on top of each other. Try as you might, they just won’t be tamed simply by separating out into distinct functions. Soon you’re lost in your own code, trapped in a Borgesian labyrinth of your own making.
First of all, our main concern at the time was Action Method Online, a heavily data-driven app. Every bit of the ‘view’ came from rendering client-side templates, so as to make the app almost entirely service-oriented. For a data-driven app, the complexities of interactions between every subsystem requires a framework with Controllers to represent the entity, whether it is a single Action Step, a post in a discussion, or the whole content area. The first framework we considered, Backbone.js, for all its strengths, is essentially still a Model-View-ViewModel (MVVM) framework. Its primary focus is still on the Model-to-View binding (and vice versa). While that is very powerful, AMO required something different.
Object.create(), the superconstructor of a new class is unnecessarily called just to define a subclass. We had been using Backbone.Model.extend solely for the ability to emulate classical inheritance patterns. However, it was a janky solution. We needed a more systematic approach.
Luckily, John Resig wrote an extension mechanism with similar signature to Backbone.js’s. His version was simple but still included powerful features like the ability to call a superclass’s implementation with
this.super(). It served as a great starting point.
I adapted Resig’s simple inheritance mechanism to also provide static inheritance, added the ability to auto-call constructors, and wrapped the whole thing in a shim that will return an AMD-style module or attach it as
jQuery.Core.Class (our internal namespace), or if that didn’t exist, simply as the global
Class. The icing on the cake was that the call signatures were entirely backward compatible with
Backbone.Model.extend(). Putting the new base Class in place was as simple as having the top-level classes extend from the new base Class.
Now we’re ready to write out the Model View and Controller classes! We’ll tackle that on another post, so stay tuned…