Making the most of Javascript namespacing
Posted on 29 October 2008 (05:33 PM)
Today's article by Robert Nyman about Javascript namespacing remembered me about my own approach, which I've been using for quite a few projects now.
If you have no clue about Javascript namespacing, go and read Robert's article. I'll wait.
Back? Good :)
The Javascript single namespace approach is, in my opinion, a great thing. I have used it quite a lot and have even set up a code snippet in Textmate which I use as a spring board for every single script I've written over the past months.
After reading Robert's article, I realized more people might benefit from the way I approach this design pattern. Here goes...
Automatically initializing your namespace
My script files always look a little something like this:
// when developing for the XYZ Corporation:var XYZCorp = {// modules go here};XYZCorp.init ();- Download this code: /code/making_the_most_of_javascript_namespacing1.txt
Every module used on the website resides inside the global XYZCorp object. After defining the XYZCorp object, I execute its init function. This init function looks a little something like this:
// when developing for the XYZ Corporation:var XYZCorp = {init: function () {for (var i in this) {if (typeof this[i].init == 'function') {this[i].init ();}}}};XYZCorp.init ();- Download this code: /code/making_the_most_of_javascript_namespacing2.txt
That's it! I loop through all members of the global XYZCorp object, and if a member contains an init method, I execute it, successfully firing up the module.
This is a very easy approach, which can be reused over and over and over again, and if you ever wish to append a new module to the site, just stuff it inside the global namespace and give it an init method. Here's an example:
// ...myModule: {init: function () {this.say ('myModule initiated!');},say: function (msg) {alert (msg);}},// ...- Download this code: /code/making_the_most_of_javascript_namespacing3.txt
If you would like to use my template in Textmate, just copy the following code into a new snippet inside the Bundle Editor:
/*** ---------------------------* Client: ${1:client-name}* URL: ${2:client-url}* Author: ${3:author-name}** ---------------------------*//*** General namespace*/var ${4:global-namespace} = {/*** Initialize all objects*/init: function () {for (var i in this) {if (typeof this[i].init == 'function') {this[i].init ();}}},$5};/*** Initialize general namespace*/$4.init ();- Download this code: /code/making_the_most_of_javascript_namespacing4.txt
Then assign it to a Tab Trigger and make sure you point the Scope Selector to source.js.
Filed under Javascript
- ← previous article: Generate unique slugs in CakePHP
- → next article: Guessing font availability with Javascript
Comments:
Interesting! When we developed the plug-in architecture for DOMAssistant, we also added support for automatically running any init methods it could find - quite handy!
I just might take you up on that for my regular JavaScript coding as well! However, I need to find a good way, for most project init code for me has to run when the DOM has loaded, so I guess I need to add finding that out as well (most likely through the JavaScript library of choice).
this comment has been quoted by Harmen Janssen
Do take me up on that, Robert :)
About the DOMready event; I've adopted the best practice to include my Javascripts at the bottom of the HTML file. That way, you can begin executing your script immediately.
On the other hand, you might want to ensure your scripts are portable by wrapping 'em up in a DOMready event... Food for thought!