Oct
30
2009
Class Based Javascript Programming
Author: mprokesOver the past few years I have worked on several javascript projects, many of which use and require a class paradigm of some sort (Open API’s). So to say the least, this is an experience which is irritating for new people and is still irritating for experienced programmers. The complexity of the problem is due mostly to the fact that there are 3-4 ways to do some things in the language (this is one of them), and none of the ways to do it really is right in any traditional sense of the word.
So for the JOY of throwing another wrench in the basket, I bring you yet ANOTHER way of doing namespaces in javascript programming, but don’t worry this should be a very pleasant experience.
First let me start off with how the problem began,
- One day matt was asked to program yet another open API, and on this day matt was sad.
- The reason was because on a previous project matt had tried an object literal style of programming (the x = {}; style), of which he found private fields were not to be found, and the requirements of an object literal (for class programming) to be very limiting with no constructor of any sort.
- He also remembered the wonders of an even earlier project, which used traditional javascript OOP programming (new operator). This style offered solutions to many of problems related to defining classes using object literals, but yet had its own set of problems. One of particular irritation was a property of javascript which makes it very difficult to build namespaced objects (which is why I think we do namespaces in JSON objects these days).
- Read about the two methods here: http://www.javascriptkit.com/javatutors/oopjs.shtml
Now being a programmer who is mandated to use jquery, he was a fish out of water. Since jquery is not a library that lends its self well to a multi-level namespace matt was forced to come up with a new method for programming namespaced API’s, regardless.. Should matt really have to rely on a library to define a namespace in javascript?? NO.
Thus I introduce to you, classical javascript OOP with namespaces. Which I would affectionately like to call “Javascript with Classes”.
Properties of javascript class programming.
- All namespace objects are anonymous instantiated singletons. Thus carry all the properties of a typical object. This levels the playing field, there are no “special” object literals.
- I have been using it for several months, it works on all browsers.
- Since everything is instantiated first, objects in the namespace may easily share references, via this.
- Namespace objects may not be instantiated, objects within the namespace may be instantiated, this method unifies classical javascript OOP and namespaces. You are able to control what objects may be instantiated with this method.
- Namespace objects have all the standard things any other function has, including privates, this, prototype, etc.
Finally, this method of javascript programming isn’t really all that special. To be honest it was looking me right in the face for the longest time, but it wasn’t until now that I get why it is important. I would say that probably the nicest thing about this method is that it unifies namespaces and classical javascript OOP, I can throw out structuring classes in object literals all together, there are also several other advantages including much cleaner code.
So enough talk, lets cut to the chase:
(The red highlighted code is the winner, when looking at simplicity)
- Lets create a namespace object called HelloWorld
Object Literal Way:
HelloWorld = {
stuff:function(){
//stuff
}
};
Classes Way:
HelloWorld = new (function(){
//stuff
})();
Classical Way:
function HelloWorld(){
//stuff
}
- Simple enough, lets now add another level to our namespace, say some animals.
Object Literal Way:
Notice: Whoa, where did function come from? Melding of 2 different concepts here. No concept of closures, you will see later how this can get extremely complicated, and even unsafe.
HelloWorld = {
"Animals":{
"Bunnie":function(){},
"Fish":function(){},
"Bear":function(){}
}
}
Javascript Class Way:
Notice: things stay consistent. The anonymous singletons are the namespaces, functions are the objects. Think about how closures come into play with this method.
HelloWorld = new (function(){
var hw = this;
hw.Animals = new (function(){
var animal = this;
animal.Bunnie = function(){};
animal.Fish = function(){};
animal.Bear = function(){};
})();
})();
Classical Way:
Notice:You can see where classical starts to break down with namespaces, you need to declare every level of the object. Highly irritating, if you have several levels. Everything is declared out of scope, so you will see later how closures factor into things. Also, unless you want your user to be able to instantiate HelloWorld on the fly, this is not a standard namespace. This is not really even correct in many ways..
HelloWorld = function(){}
HelloWorld.Animals = function(){};
HelloWorld.Animals.Bunnie = function(){};
HelloWorld.Animals.Fish = function(){};
HelloWorld.Animals.Bear = function(){};
- Excellent, now lets say that we wanted one function in the object domain to access another.
Object Literal Way:
Notice: Humm, notice how we had to type in the full object path here, this is one of the downfalls of object literals, in the fact that scope is not retained in the literal. This becomes highly irritating if you at all try to create any sort of complexed javascript object model.
HelloWorld = {
Animals:{
Bunnie:function(){alert('Bunny');},
Fish:function(){alert('Fish');},
Bear:function(){
alert('A Bear Has A');
HelloWorld.Animals.Fish();
}
}
}
Javascript Class Way:
Notice: Humm, this is nice, notice the fact that since everything is in a closure, we are able to retain scope. We don’t have to work down the heirarchy, just use the closes parent object to reference sub-objects. If you do lots of api calls which is what about 30% of code is, this can greatly enhance how clean code is.
HelloWorld = new (function(){
var hw = this;
hw.Animals = new (function(){
var animal = this;
animal.Bunnie = function(){alert('Bunny');};
animal.Fish = function(){alert('Fish');};
animal.Bear = function(){
alert('A Bear Has A');
animal.Fish();
};
})();
})();
Classical Way:
Notice:Really, classical is getting worse here, and we have the same problem that the object literal has, as the fact that there is no retention of scope.
HelloWorld = function(){}
HelloWorld.Animals = function(){};
HelloWorld.Animals.Bunnie = function(){alert('Bunnie');};
HelloWorld.Animals.Fish = function(){alert('Fish');};
HelloWorld.Animals.Bear = function(){
alert('A Bear Has A');
HelloWorld.Animals.Fish();
};
- Lets say that we wanted to create a private field in a domain object.
Object Literal Way:
Its not possible to do it.
Javascript Class Way:
Due to the fact that sub classes are defined in the parent class scope is inherent, and privates become easy to achieve. Privates only exist in the confines of a { and }, so a parent object could never access a child private.
HelloWorld = new (function(){
var hw = this;
var privateHello = 'Hello World';
hw.Animals = new (function(){
var animal = this;
animal.Bunnie = function(){alert('Bunny');};
animal.Fish = function(){alert('Fish');};
animal.Bear = function(){
alert('A Bear Has A');
animal.Fish();
alert(privateHello);
};
})();
})();
Classical Way:
You can define a private variable in the HelloWorld Object, but due to scope issues you can’t share it with any other object.. *sigh*.
HelloWorld = function(){var privateHello = 'Hello World';}
HelloWorld.Animals = function(){};
HelloWorld.Animals.Bunnie = function(){alert('Bunnie');};
HelloWorld.Animals.Fish = function(){alert('Fish');};
HelloWorld.Animals.Bear = function(){
alert('A Bear Has A');
HelloWorld.Animals.Fish();
};
Hummm whenever we start to do anything complexed, a clear winner is beginning to emerge here. Lets continue, and try some other common programming practices. How about we try out constructors. … More on this a bit later.. getting late…


