Widget JavaScript, the Un-series: Part 0 (Namespacing and the Module Pattern)

May 13, 2008, 3:45 pm · 0 comments · Filed under: JavaScript, Widgets

I’m not big on series of blog posts. Others have done it successfully, but personally I’ve promised this kind of thing before and not delivered. So, I’m not making any promises that this series will get past Part 0, but please know I have the best of intentions. If all goes as hoped, over the next however-many posts I will provide a few useful JavaScript code snippets that Dashboard widget authors can take and easily adapt to their own needs. This is based on my experience authoring nearly 20 widgets over the last 3 years. As you can imagine, some patterns have emerged. In this pre-series post, I will discuss a couple of concepts important to understanding my examples (you know, if I get around to posting them): namespacing and the module pattern.

andrew.hedges.name



Can your web browser do this?

You’ll never get rich digging a ditch, nor building Dashboard widgets.

A Kryptonite™ lock can be defeated in 11 seconds, but you still lock your bike, right?

Gaining Twitter followers is a little like losing weight. You have to try.

Over or under? It’s the age-old question when it comes to the orientation of toilet paper rolls.

Subscribe


Meta Me

I am a web developer, recently returned to the States after 3 years in New Zealand. I’m into my family, photography and frisbee sports.

Blip.fm Digg Facebook LinkedIn Stack Overflow Twitter Zooomr

Nothing will benefit human health and increase chances for survival of life on earth as much as the evolution to a vegetarian diet.
Albert Einstein


Topics

Apple · AppleScript · Business · Coda · CSS · Dashboard · Design · Google · InSTEDD · JavaScript · jQuery · Life · Marketing · Music · New Mexico · New Zealand · Open Source Software · Photography · PHP · Politics · Ruby on Rails · Scree · Subversion (SVN) · Twitter · Usability · Web Development · Widgets


Archives


Most Popular

CSS Fast Nav: Because (perception of) speed matters! · Personal Branding for Introverts · Stupid WebKit Tricks · Add an interactive legend to a MarkerManager managed Google Map · Dude. Mikeyy can’t even spell his own name. · Dashboard Widgets for Fun and Profit · Animating your iPhone web application · How-to recover from checksum mismatch errors in SVN · Why Apple can afford to charge so little for Snow Leopard · The first 48 hours of PHP Function Reference, by the numbers


Most Recent

CSS Fast Nav: Because (perception of) speed matters! · When is a global variable not a variable? · Our misguided culture of cool · InSTEDD: Open Source Software that saves lives · Add an interactive legend to a MarkerManager managed Google Map · Personal Branding for Introverts · Moments of Rangitoto · Some Twitter conventions · Why Apple can afford to charge so little for Snow Leopard · Stupid WebKit Tricks


Twitshirt

Twitshirt is a tweet on a shirt. Buy the one below or check out my most recent tweets.

There is truth. The rest is fashion.

See a random Twitshirt-worthy tweet.


Friends

80/20 · 90 Seven Design · Alyson Hurt · Andrew Nimick · Apps & Hats · Ben Young · Brian Arnold · Brian Warren · Carl Bolter · Chris Burgess · Christine Morris · Cristina Stoian · Daniel Lyons · Daniel Schwartz · David Hedges · Hamish Campbell · Jochen Daum · John Visser · Joseph McLaughlin · Joshua Sallach · Julian Pistorius · Justine Sanderson · Kalena Jordan · Katie Graham · Kelly Green · Kevin Potis · Mark Bixby · Matt Henry · Method Arts · Morgan Pyne · Peter Michaux · Philip Tellis · Piers Harding · Rebecca Murphey · Reid Givens · Rey Bango · Rhett Anderson · Richard Paul · Rob Pongsajapan · Robin Taylor · Ryan Park · Shaun Lee · Simon Young · Su Yin Khoo · Toni Barrett · Vaughan Rowsell · Vincent Thomé · Voom Studio


Recommended Books on
Web Development

My bias is for references over “cookbooks.” I want to know all of my options, not just one way to do something. Show me the why as well as the how and I am happy.

JavaScript: The Good Parts · Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries · JavaScript: The Definitive Guide · Designing with Web Standards · CSS: The Definitive Guide · Prioritizing Web Usability · The Elements of User Experience · Web ReDesign: Workflow that Works · Don't Make Me Think: A Common Sense Approach to Web Usability


Contact Info

Contact info for Andrew Hedges


I’ve hosted this website with pair Networks since 1997. They rock.

This blog is powered by…software I wrote.

Feeling generous? Knock yourself out!

Namespacing

You namespace your JavaScript, right? Right?!

Just because Prototype doesn’t do it doesn’t mean you shouldn’t. Better to follow the example of jQuery, YUI, and Dojo and put your JavaScript in a tidy little top-level object so it has less chance of stomping on or getting stomped on by other scripts. I won’t name names, but I recently worked on a site where we were told to include 3rd party ad serving code that put the cleverly named function random() in the global namespace. I’m surprised that’s not used as example #1 in the dictionary for the word “naive.”

Now that I’ve ridiculed you into submission, I’m going to say something you might consider a bit contradictory. In widgets, you don’t have to be so strict about namespacing. There, I’ve said it. Sue me. But first, let me explain.

Unlike the WWW (Wild West Web), where you’re not always in control of all the JavaScript on your pages, in a widget, the environment is more controlled, so it’s easier to know what’s going on. So, rather than putting all of your JavaScript in one namespace (like I myself have done in all my [to-date] published widgets, again with the contradictions, sheesh!), I recommend grouping like functionality into namespaces.

For example, I plan to talk about (though I make no promises, you understand) preferences and version checking. Each of these could go in their own namespace. You know, like PREFS and, oh, I don’t know, maybe VERSION.

There’s nothing magical about this from a coding perspective. Here’s a simple example:

var MYNAMESPACE = {};
MYNAMESPACE.getFunky = function () {
    // do funky stuff
};
MYNAMESPACE.getFunky();

Tidy. Orderly. Encapsulated.

Module Pattern

The module pattern is a technique for organizing large JavaScripts into public and private members. It was popularized by Douglas Crockford and has been blogged about (and criticized) all over the flipping shop.

One of the important concepts you need to understand to “get” the module pattern is closures. Go read this example-laden overview of closures as they are implemented in JavaScript and come back. I’ll wait.

My use of the module pattern is pretty faithful to the original. The purpose of it, for me, is to be able to create both public and private variables and methods in tight, little, namespaced objects. Here’s an example.

var MYOBJ;
MYOBJ = (function () {

    // private variable
    var _rgxp;
    _rgxp = /^abc$/i;

    // private method
    var _isMatch;
    _isMatch = function (str) {
        return _rgxp.test(str);
    };

    // public method
    return {
        ask: function () {
            var input;
            input = prompt('What are the first 3 letters \
                of the alphabet?');
            (_isMatch(input))? alert('Correct!') : \
                alert('Wrong!');
        }
    };

})();

MYOBJ.ask();

As I said above, this has the advantage of being tidy and encapsulated. I can also run this with confidence that my regular expression (because it’s assigned to a private variable) hasn’t been stomped. The example is contrived, but hopefully you get the idea.

Bonus!

As a reward to myself for finishing each of the posts in this “un-series,” I plan to (again, no promises!) include at the end a little “bonus” code I use to make my widget-building life a little easier. Enjoy!

If you don’t currently localize your widgets, you should. It’s pretty easy and it not only gives you a wider audience for your work, it makes your non-native language users feel all warm and fuzzy.

The following function is based on one generated by Dashcode, Apple’s excellent Dashboard development IDE. Usage is simple. You tell your string you want it localized and it takes care of looking up the string in the localizedStrings array from the proper localized file, and replacing it out.

String.prototype.localize = function () {
    try {
        var string = localizedStrings[this] || this;
    } catch (e) {}
    return string;
}
var localString = 'My string'.localize();

In my day job, we use the Symfony PHP framework. Symfony creates a function for localizing strings: __ (That’s 2 underscores, if you’re wondering.)

Being used to the pattern __('My string'), I decided to make it so I could call my localization String method in the same way. It’s simple, really.

__ = function (str) {
    return str.localize();
}
var localString = __('My string');

Conclusion

OK, that’s it. I hoped you enjoyed this pre-installment of my un-series. I hope to post the next one, real soon now…


Short URL to this article:
Tweet this article!


Comments close automatically after 90 days.
Still have something to say? Drop me a line!

Possibly related posts