So the convention requires that instead of this:
var ccc; var aaa; var bbb;
… you do this:
var aaa; var bbb; var ccc;
By ordering the variables alphabetically we have supposedly made it easier to find variable names.
I should probably use a real world example to demonstrate its true benefit, so here’s a chunk of variables from jQuery:
var rformElems = /^(?:textarea|input|select)$/i, rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/;
They’re using some quasi-hungarian notation which, it could be argued, negates the benefits of alphabetical ordering, so let’s remove all of the
r prefixxes so that we’ve got a good example to work with:
var formElems = /^(?:textarea|input|select)$/i, typenamespace = /^([^\.]*)?(?:\.(.+))?$/, hoverHack = /(?:^|\s)hover(\.\S+)?\b/, keyEvent = /^key/, mouseEvent = /^(?:mouse|contextmenu)|click/, focusMorph = /^(?:focusinfocus|focusoutblur)$/, quickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/;
Okay, now let’s re-order according to the convention:
var focusMorph = /^(?:focusinfocus|focusoutblur)$/, formElems = /^(?:textarea|input|select)$/i, hoverHack = /(?:^|\s)hover(\.\S+)?\b/, keyEvent = /^key/, mouseEvent = /^(?:mouse|contextmenu)|click/, quickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, typenamespace = /^([^\.]*)?(?:\.(.+))?$/;
Did you notice the difference? The convention suggests that it is now easier for programmers to come along and find the variable
focusMorph because it is within an alphabetically sorted list. I have doubts about this though.
For me, this variable list is no easier to navigate than before. I’m probably below average in “alphabet skill” though. Sometimes I find myself reading out the alphabet internally so I can try to remember if K really does come before M. It’s sad but true.
It could very well be that this is just one of those things that only affects me. And that’s fine. I still would like to continue with my exploration of this convention though.
This convention can become a problem when, for example, one variable depends on a previous variable’s assignment. For example:
var radians = foo.getRadians(), angle = radians / Math.PI * 180, // we need radians to be defined ...;
With the convention applied:
var angle = radians / Math.PI * 180, radians = foo.getRadians(), ...;
But that doesn’t work anymore. When the first line runs,
radians is undefined. Of course, in this example, I could just get rid of the
radians variable and use
foo.getRadians() straight off. Yes, I could do that. But this is just an example, and I have battled with this quandary many times without such simple solutions.
So, strictly, how does one solve this, supposing it was a trickier case? Actually, wait — let’s explore why we’re solving this. Is this a programming problem? Nope, this is an issue born from tireless compliance to standards and conventions.
Is it worth fixing? Shall I? –
var angle, radians = foo.getRadians(), ...; angle = radians / Math.PI * 180;
I fixed it! The variable declarations are in order. But at what cost? I’ve moved down the actual assignment of
angle to after the declarations.
But doing this would not serve the convention’s purpose because we haven’t made it easier to find
angle = ....
Okay, so I guess the correct thing to do would be to rename one of the variables so that they’re ordered correctly. Now, I’m sitting here thinking of what I should name a variable. I’m looking for a word that means the same as
angle but starts with a letter beyond
r. This is starting to feel less like programming and more like a game.
Let’s be honest though. Nobody is going to have trouble finding either of these variables. There are only two. And I would argue that the jQuery variable block is also easily navigable.
As programmers, surely it is our responsibility to ensure that our code is well abstracted and that we separate our concerns. If we do this effectively we should rarely end up with lists of more than five variables in each function/method, give or take a few.
If you have a list of variables that is difficult to navigate then you’re problem isn’t going to be fixed by applying a convention — it’s going to be fixed by abstracting code and separating concerns.
Also, more often than not, the way in which I order variables is governed by the way in which they relate to each-other, semantically, and the functional story that is told through their assignments, e.g.
var data = getData(); var id = data.id; var base = getBaseById(id); // [rest of the function] // usage of `data`, `id` and `base` etc.
A story is told through variable assignment, just like it is through flow control.
At least in my personal code I make it a policy to not let conventions have undue authority. I don’t code for conventions. I didn’t make this website so that it would pass HTML validation. I don’t worry about JSLint. I don’t lie awake at night wondering where I’ll find that lost semi-colon!
What I do worry about is creating functional and readable code. Sometimes it’s difficult and I end up with a mess. But that mess isn’t going to be fixed by stringent coding standards — it’s going to be fixed by repeated application of my programming abilities to abstract and separate.