I have an issue with not being able to read my own code. Other developers, I am sure, can relate. Especially when I have put a great deal of effort into a single file. Often this is a JavaScript file that has a whole lot of ability but not a whole lot of functionality. jQuery is one of my favorite frameworks. It is easy to use and easy to attach to. So for example, let us say I have a function that needs to be able to be triggered on a DOM element. I could send “this” to the function over and over again. Or I could let jQuery do all the work for me. I am lazy, after all.
jQuery.fn.destroy = function() { return this.each(function() { $(this).remove(); }); };
With this, I can remove any DOM element by calling destroy. Pointless, yes, but it works and shows what I mean.
Simple enough. But what if I want options. What if I need to do more things but I should really only take one name from jQuery, right? What about this?
jQuery.fn.stuff = function(opt) { return this.each(function() { switch(opt) { case 'destroy': $(this).remove(); break; case 'alert': alert(this.tagName); break; } }); };
Now, I can destroy or I can alert the user that the DOM element was a TABLE. Again, this is an example and not something anyone would actually use.
But, what if I needed to add lots of functionality and my function just ended up overflowing with an annoying level of switch statements. Eventually, I get to the point where I cannot read my own code or find the place in my code that I need to adjust.
Now for my easier, cleaner solution.
First, I create an object. In this example, we will name my object Jeff.
var jeff = {};
Now, let me give Jeff a function.
// This is a pointless function to remove DOM elements. jeff.destroy = function(obj) { jQuery(obj).remove(); return obj; };
Jeff needs another function.
// This is a pointless function to send a message. jeff.alert = function(obj) { alert(obj.tagName); return obj; };
I can repeat this forever with as many functions as I want:
- Commenting is easy and clean
- There is no ugly switch statement
But what does this have to do with jQuery? Here is my easier jQuery.
jQuery.fn.jeff = function(opt) { // Unlike the highlander, there can be more than one. return this.each(function(){ // We like options that make sense. if(typeof opt === 'string') { // Make sure Jeff knows what to do first. if(typeof jeff[opt] === 'function') { // Tell Jeff what to do. jeff[opt](this); } else { // Let the user know that Jeff doesn't know that trick. console.error('Jeff does not have a function named "' + opt + '".'); } } else { // The user sent Jeff something silly. console.error('Jeff is really confused by what you are trying to do.'); } }); };
And there we have it.