Category Archives: inheritance

Dojo.declare Vs Javascriptzilla

This other day I’m like coding and stuff when I suddenly gained a whole new level of appreciation for what dojo.declare does for humanity and especially javascript developers. It’s hard to describe… it’s just … wow!

Quick background. Javascript was apparently supposed to come off as a simplified version of Java. As part of that simplification, rather than use classes for defining object blueprints, it uses object prototypes. You know the prototype pattern, right? It’s when you create one model object and clone it each time you want to create a new object of that type (analogous to creating a class and instantiating the class each time you want a new object). That gets you rid of having to create classes at all so you only deal with objects. However, by itself that’s not sufficient – you still need a constructor, which is that piece of logic that initializes the object when you create it. In addition, you need inheritance, meaning if a property or method is not attached to this object, check its superclass, and then the superclass of that… all the way up.

We can certainly define the constructor as a function, but where should we keep it so that it remains connected to the prototype object? In what’s no doubt one of the biggest hacks of the century, javascript decided to have that constructor function masquerade as the class (a concept it apparently tried to avoid all along), and attach the prototype object to that function under the prototype property. Strangely enough, the prototype object itself has a constructor property that points back to the function. So now you can totally invoke the constructor function as a regular function (and expect the unexpected if you do that), but what you really want is invoke it using the new operator, which is the psychedelic way to tell the machine to clone the attached prototype object and initialize it by running the constructor function on it!

Sound confusing? Adding inheritance to the mix makes it about ten times worse. Inheritance needs a few things like:

  • Creating a class instance should invoke the superclass constructor first (all the way up)
  • Invoking an inherited method should work as expected
  • Changing a static value in a superclass should be reflected in all the subclasses that don’t override it

Javascript immediately fails the first one because it doesn’t chain constructors. It can be done, but you have to do it yourself. The last two have been a source of some confusion but generally can be resolved by using javascript’s prototypal inheritance. The confusion arises from simplistic implementations that mixed in properties of all super-prototypes into a single prototype object, thus creating a denormalized object prototype; the problem with such implementations is that they fail the last point – changing a static value in a super-prototype does not get automatically reflected onto the sub-prototypes. This last issue is really more of a documentation problem since it’s resolved by the correct usage of prototypal inheritance.

Dojo.declare solves the aforementioned problems without much fuss and does a whole lot more. While javascript’s native prototypal inheritance solves the problem of single inheritance (except for the constructor part), Dojo takes that whole concept further to implement multiple inheritance. The classic problem with multiple inheritance revolves around collisions – when the same method is present in both left and right superclass (as in the Diamond problem). Dojo utilizes a relatively recent concept known as C3 linearization (aka C3 Method Resolution Order) to correctly simulate multiple inheritance. It has to simulate it because each object can only have a single super-prototype, so that’s done through some creative use of mixins. Of course dojo users don’t need to worry about it because it JustWorks(TM).

The result of calling dojo.declare is very much the same as that of manually creating a function that masquerades as your constructor/class, assigning it a prototype object, establishing the prototype and constructor chain, etc. Dojo.declare returns a completely normal-looking function object, which we can call usingĀ new to create new instances. Even small details are taken care of, such as if it’s a named function, dojo adds it to the global scope for us, and if called without new disaster is averted. As if that’s not enough, the mixin mechanism allows taking bare-bones interfaces and mixing in existing partial implementations into them – all using a single call to dojo.declare!