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.
One reply on “Argumentative”
<rant>
That’s grade A filth.
My take on designing code is the longer it (usually) takes to understand the code, the more complicated the problem. Hence my investment to actually understanding the code.
In this case, 5 minutes to confirm what you’ve stated in your post is exactly right – is about 4m55 too long for the purpose the code actually served!
</rant>