I spent a little while looking at mootools yesterday for a colleague. It’s yet another JavaScript library. My colleague was wondering how to restrict the Accordion effect so it applied once to each area of content on the page, rather than once for the whole page (each content area has multiple bits of content where only one should be visible).
As usual, I just headed straight for the source code (Accordion.js). Inside, I found the best abuse of JavaScript I’ve seen in a while.
initialize: function(){ var options, togglers, elements, container; $each(arguments, function(argument, i){ switch($type(argument)){ case 'object': options = argument; break; case 'element': container = $(argument); break; default: var temp = $$(argument); if (!togglers) togglers = temp; else elements = temp; } }); // … }
Now what exactly does this do? It’s pretty different from the usual JavaScript function usage:
var initialize = function (options, togglers, elements, container) { … }
The first thing of interest is the first parameter to $each
: arguments. A little known feature of JavaScript is that every function has an array-like object of all its arguments available. You can find get a reference to the function that you’re in, which is sometimes useful.
Here, it’s being used to accept an arbitrary number of arguments, in any order. To be quite frank, it’s a bit of a mess. This is my understanding of the above code:
- You can pass in up to four arguments.
- You can pass in more, but we only get 4 parameters out of it.
- The last JavaScript object will get treated as a set of options.
- The last element passed in will be used as “container”.
- The first non object|element will be passed to $$ and treated as the set of “togglers”.
- The last non object|element arguments will be passed through $$ and treated as the elements to be shown/hidden.
Is that right? I’ve been looking at it for a bit and still not 100% sure.
To me, this is a fine example of taking the flexibility of JavaScript just a little too far.