After a bit of searching among the variety of approaches out there, I ended up using the parasitic inheritance model proposed by Douglas Crockford. The essence of this approach is having the constructor for a subclass instantiate an instance of its superclass, modify it by adding methods, and then returning the modified object. A simple inheritance would look like this:
1: car= function(manufacturer) {2: // class we inherit from
3: var me = new vehicle(manufacturer);
4: me.honkHorn = new function() {
5: // do stuff
6: };7: return me;
8: } 9: 10: var myBlueVolvo = new car= ("Volvo");
This seems pretty natural and gives most of what I was looking for (code reuse and some variable hiding) without torturing the language too badly.
I do occasionally need to call methods in the superclass from the subclass though. Douglas implements a relatively complex "sugar" that automatically provides reference to a "uber" object that mimics the "base" object in C#, but I was worried that this was a lot of extra code for something I really only do with a handful of functions. Complexity is bad.
Instead, when I need to reference an overridden method in the superclass, I took advantage of JavaScript closures to provide a simple way to call a superclass method. Here is an example:
1: var super = me.honkHorn; 2: me.honkHorn = new function() {
3: // call the method on the superclass
4: super.honkHorn(); 5: 6: // now do stuff in the subclass
7: };By saving the superclass function in the super var, it gets captured and is still around to be called, even though it is no longer references by the new object as a public function.