Javascript inheritance without loosing class names

There are a LOT of articles out there that talk about Javascript inheritance, or even object-oriented javascript in general. There’s been thousands of frameworks that have provided javascript with the notions of encapsulation, classes, etc. This is probably because prototype-based programming is not intuitive to all those who work regularly with object-based languages such as java, php, ruby, c#, etc. Just look for object-oriented javascript stuff on github, you’ll find thousands of open-source frameworks / snippets… So why do people bother so much about turning javascript into something it’s not?

Well my personal thought is that it’s actually a good exercice. It really helps one understand and appreciate the depths of the prototype-way of thinking. In fact, I think that all javascript developers should create their own $.extend framework so that they may discover the subtleties and power of prototypes.

Anyways… I was reading some of the most famous inheritance scripts out there, starting out with this bright snippet from John Resig. I also went through the sources of the most appreciated related github projects (ooliboorja to credit a few) and quickly realized that all of them shared a big issue, which is best described in one of John’s comments : “@Justin: I don’t think there’s a reasonable way to actually assign a name to the classes, which is unfortunate.”

The problem

There are two ways to define a class in javascript:

1. var myclass = function(){...}
2. function myclass(){...}

Even though they may look alike, those 2 methods are very different :

1. creates a function that doesn’t have a name (anonymous function) and assigns it to the variable myclass
2. declares the function named myclass

It is important to note that “you cannot change the name of a function, this property is read-only.”. In other words, once you have started using an anonymous function to create your class, you will never be in control of the class name.

The impact

Let’s take John’s Resig’s code snippet and apply it in the console:

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
});
 
var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  }
});
 
var p = new Person(true); 
var n = new Ninja();

Both object’s class names are ‘Class’:

p.constructor.name; // 'Class'
n.constructor.name; // 'Class'

While this may not be a problem when dealing with small examples, it becomes a huge PITA when debugging a big javascript project based on anonymous functions. Try making an HTML5 game with it and you will see how fast it gets on your nerves. hence I looked at about 20 different pieces of code but the same issue / code pattern was there. In fact I haven’t seen any framework that could provide me with ninjas beeing Ninjas and persons beeing Persons (did I miss it along the way??).

So last night I wrote my own little inheritance snippet. It uses dynamic function naming to circumvent the issue above:

moo.js

There are a couple of objectives I wanted to achieve:

– achieve basic inheritance
– allow subclass methods to override / call upon their super methods
– have classes retain their class names
– support for event management

The code is released under the MIT licence. Feel free to use it at your convenience. I think it can be very useful for games or other object-oriented programs. It’s been tested with jasmine.

Project home with its documentation
Source code hosted on github

I’m sure it can be improved and i’m always open for feedback and criticsm so if you’ve got something to say, use the comments section below or create an issue in the github project.

Leave a Reply

Your email address will not be published. Required fields are marked *