- Ad hoc inheritance – This is a common(?) homebrew technique for allowing prototypes to leverage the code in objects further up the prototype-food chain. Methods are overridden by keeping a reference to the parent method in a separate property , which can then be invoked as needed. It’s fast but not very pretty, and it’s arguable whether or not this qualifies as real “OO” inheritance.
- Prototype-style inheritance – Prototype uses a strategy inspired by Alex Arenell’s Inheritance library. Subclass methods declare a “$super” argument that is set up by Prototype to reference the superclass’ method.
- Base2-style inheritance – Dean Edwards’ library. Subclass methods invoke “this.base()” to call their superclass’ implementation.
- John Resig inheritance – JR, of jquery fame, experimented with a Base2 variant which he published on his blog. It’s a bit simpler than Base2, but seemed worth testing.
- [Update] MooTools – For you MooTools fans out there, I believe that library uses the same approach that Dean Edwards came up with for Base2, so performance should be similar. aNieto2K links to his test in the comments, below, if you’d like to verify this for yourself. (I’d add this to the test, but Prototype and Moo collide over the use of the ‘Class’ name)
Tests were performed by using JSLitmus to create a Inheritance Performance testbed. In it, I create a base class and subclass using each of the above approaches. Each base class has a single method, “foobar” which is overridden, and invoked by, the corresponding subclass. The rate at which objects could be instantiated for each base class and subclass was tested. The rate at which a method could be invoked on the base classes and subclasses was also tested. Here are the results (first three are on MacBook – the IE and Chrome tests are on a Dell laptop):
There are pros and cons to each technique. For sheer balls-out performance you’re best off using the ad-hoc “move aside” approach. That’s only really important if you’re making 100,000’s 1,000s of calls per second to overridden methods, however. Both Base2 and Resig’s approach have decent invocation performance, but Base2 can be a bit slow at object creation.
The most interesting result was the utter crap-tastic performance of Prototype. When calling methods that use $super it’s consistently 20x slower than the other solutions. (Likely a result of the additional closure functions it requires). Regardless, this is definitely something to watch out for for any application that makes heavy use of subclassing. Or, rather, of subclassed methods.