I began developing with JavaScript more than 10 years ago in order to handle DOM updates on the client-side. At this time, this usage was called DHTML and I was one of the few Java developers that had some interest in it. Still, JavaScript was considered a second-class language, something that was somewhat necessary but wasn’t professional enough.
Fast-forward: the year is 2013 and JavaScript is everywhere:
- developers are using JavaScript both server- and client-side
- HTML5 uses JavaScript for dynamic behaviour
- Client-side data binding is featured by major JavaScript frameworks to build modern web applications
On my part, I’m still the same developer in regard to JavaScript. There always had been more important matters to pursue, and I find myself lost when looking at JavaScript most advanced features. At Devoxx France, I was extremely impressed by HTML5 animation features, and I wanted to play with them in my spare time. I had to develop some JavaScript, with right scoping and good isolation.
As opposed to Java, JavaScript provides global variables. Also, JavaScript functions are available from everywhere. Isolation is not built-in, but has to be designed. The first rule is: do not use global variables. Global variables are a bug waiting to happen, encapsulation should be enforced, period.
Also, Java provides namespaces, a way to create different classes with the same name and still avoid collision, even when using other third-party libraries. The first way I stumbled upon to achieve this made my heart sink:
var CustomNamespace = CustomNamespace || {};
CustomNamespace.doThis = function() {
...
}
Not only do I find this extremely unwieldy from a developer point of view as members do not have to be encompassed in the same block, it doesn’t provide isolation: members are accessible.
Next I found the Module pattern, which resolves both problems: code is written inside a single block, and provides ways to offer both internal and public members by using closures:
var CustomNamespace = (function() {
var varPrivate = ...;
function doThatPrivate() {
...
}
return {
doThisPublic: function() {
...
},
doThisPublic2: function() {
...
}
};
})();
This syntax let use encapsulate variables and functions we want to keep private while providing publicly-available functions under a specific namespace. Usage is as follow:
CustomNamespace.doThisPublic();
I find this syntax clear enough to write and easy to use, while providing namespace and restricted access to only desired members. Of course, being newbie in this field, I haven’t encountered disadvantages of it… yet.