Writing better javascript – Part 5
Use the module pattern to better organize your code.
Good JavaScript programming practices will help you debug and diagnose problems better. It will also keep you sane when the applications grow bigger and will be more maintainable. One of the things that I tend to do these days when I see any applications developed using the ESRI JS API, Google Maps API or the VirtualEarth API is to do a “View Page Source” on the we page. It is surprising to see many of those applications have a considerable amount of application logic on the web page itself as a series of javascript functions. I have been using the JavaScript module pattern to better organize my code and I find it satisfactory for most of my requirements. Obviously, that is not the only way to organize your code but I like it because it helps me think in terms of classes with private & public properties and methods.
Creating a class using the module pattern is pretty simple. The snippet below illustrates how to create a new class. It is only an illustration of the technique and doesn’t mean much.
var MapManager = function(/*constructor arguments defined here*/) {
//Declare private variables here
var _mapElement;//Declare private methods here
var _addLayer = function(layer) {
//private properties and methods CAN be accessed here
//public properties and methods CANNOT be accessed here//add the layer here
};return {
//Declare public properties here
element: _mapElement,
data: new Object(),//Declare public methods here
addLayer: function(layer) {
//private properties and methods CAN be accessed here
_addLayer(layer);
}
};
};
The class ‘MapManager’ defined above defines its private and public memebers. When an instance of the ‘MapManager’ class is created the instance returned can only be used to access and change its public properties and methods and not its private members. The ‘new’ keyword can be used to create an instance of the ‘MapManger’ class like below.
var instance = new MapManager();
Just for a little insight into the technique, when you create an instance of the class, the object that is defined as a JSON literal after the ‘return’ keyword is the object that gets returned. And this returned object still has access to the private members in the class definition above because of the concept of closures in JavaScript.
This technique should be satisfactory for most simple design needs but most JavaScript frameworks offer their own technique to create classes, inherit from them and other advanced OO concepts. I hope to post at a later time on inheritance when using the module pattern.
I would suggest using the prototype pattern instead. With your approach a new instance of the addLayer function is created on each instance, but if you are declaring it on a prototype instead, it will only be stored in memory once:
MapManager = function(mapElement) {
this._element = mapElement;
this._data = {};
this._layers = [];
}
MapManager.protytype = {
addLayer : function(layer) {
Array.add(this._layers, layer);
}
}
var instance = new MapManager(myMap);
instance.addLayer(myLayer);
Hi Morten,
The module pattern is flexible enough to allow only one instance in memory also. You just have to end the function definition with ‘()’. Meaning the function gets executed already and you can’t say new anymore. It is more like a singleton pattern if you will.
Also, if I have 2 or maps on my page, then I will more MapManagers also. So, the module pattern is more flexible that way also.
Thank You,
Vish
I’d recommend using namespaces as well. In cases where there could potentially be JS functions from multiple sources on one page, this prevents having functions overwriting each other.
Hi Emmster,
Thank for you for the recommendation. I do use namespaces for better organization and to avoid conflicts. I just wanted to keep the post simple for starters.
Vish
Although these posts are mainly about JavaScript in general, but if you are using a toolkit (for example Dojo in ArcGIS JavaScript API), it is better to follow the same object patterns in your code. For creating classes in Dojo, please see Declaring a Class. I would recommend going through the whole Object Orientation chapter of the Dojo book.
Hi Jayant,
I am aware of the Dojo OO capabilities. But it might be just preference thing that I actually like the module pattern better. I understand that creating classes style is a little more powerful and flexible. But there is also not a way to hide data from the consumers (like private members). It is good if you want to hack your way around it. Like, for eg. some of things that I think are missing in the JS API public methods or properties like a base layer property on the map, can be worked around by just accessing the map._baseLayer which is supposed to be hidden or atleast that was the developer’s intent.
But I agree that each developer needs to make that decision based on his requirements and what he/she is comfortable with.
Thank You,
Vish
[…] while ago I had written about using the javascript module pattern to organize code a little better. But off late, I have moved away from using the module pattern […]