A criticism of the Single Var Pattern in JavaScript, and a simple alternative

The Single Var Pattern is a JavaScript design pattern where for each scope, one var statement and only one var statement is used to declare all the variables for the current scope. It’s used to help prevent logical confusion (variables being hoisted half-way through a scope are declared before being necessarily defined), collisions due to a variable being declared twice, and from unused variables being created and forgotten during refactoring.

In general the Single Var Pattern is a great idea and works very well, but it can quickly become difficult to work with, understand, debug and read. For that reason, I follow the guidelines except for one small difference.

This is the Single Var Pattern:

function () { var declare = 'all' , your = 'variables' , using = 'a' , single = 'var' , statement = 'then' , semicolon ; // Everything else. }

And this is what I do instead. I call it Vars At The Top.

function () { var declare = 'all' ; var the = 'variables' ; var at = 'the' ; var topOfTheScope = 'but' ; var using = 'separate' ; var varStatements ; // Everything else. }

Why do I do this? Read on…

You can’t step over the Single Var Pattern

Those of you who use Chrome Developer Tools will probably be familiar with this toolbar:

Let’s focus on the orange-circled button first. As you may know, this little guy is called the ‘Step Over’ button, and what he does is take you from one line to the next. Let’s say that there’s a problem on line 4 in this screenshot from Dev Tools because the argument doWork is a function that is producing some unexpected behaviour:

We have a breakpoint at line 2 which is currently where we’re at. We know there’s something wrong with the doWork function, and for argument’s sake let’s say we can’t easily find it in the code. So to have a look inside that function we’re gonna use the button highlighted with a blue circle in the first image: the ‘Step Into’ button. But first, we need to Step Over a couple of times. What we expect to happen is to go to line 3 after the first click of the button, and Line 4 after the second.

Well, that’s a shame. What we see here is Dev Tools interpreting the whole thing as one line for the purposes of stepping over.

I will say, though, at least Dev Tools identifies that the error is on line 4. It’s just annoying when debugging someone else’s code - or even your own - if you can’t step into a function they’re using, especially when it’s been passed in as an argument.

EDIT: Someone in the comments on Reddit pointed out to me that it is in fact possible to step into these functions using SVP, but if there are multiple functions being used, you must step into each one and then out again until you get to the one you want. Anyway, my mistake. Thank you, html6dev on Reddit

Prone to errors

I recently read a post by Yoav Rubin which pointed out how a little mistake in using the Single Var Pattern can lead to a grave error. I’ll quote directly from what he gave as examples. The first one is how the developer intended to write their code, and what the effect for each variable is.

var someData = 'testing' , // local within the function otherData = 'data1' , // local within the function moreData = 'data2' ; // local within the function

And now, what if they forget just a single comma after the first variable?

var someData = 'testing' // local within the function otherData = 'data1' , // global moreData = 'data2' ; // global

JavaScript engines will insert semi-colons at the end of lines which do not have them (or a comma), and as you may know, a variable declaration without a var statement means a global variable declaration, which could be a huge problem.

This is a small but significant thing, which in my opinion can really slow down the development process.

Because the statement is essentially one long line, it has to compile properly as a single line every time we run the program, which can become a pain in the butt to maintain.

Often, during the process of developing something I’ll end up commenting out lines of code bit-by-bit and sometimes commenting out entire variable declarations to see if, for some reason, this line is causing trouble. Let’s look at an example:

var dodgyVar1 = doSomethingDodgy ( 'value' ), goodVar1 = 'value' , goodVar2 = 'value' , dodgyVar2 = doSomethingDodgy ( 'value' ); // Do some stuff here with those variables

At some point in writing this code I decide to comment out dodgyVar1 and dodgyVar2 , because I suspect they’re doing something dodgy. Since I use Sublime Text, I select both lines 1 and 4 ( CMD + Click ) to have a cursor on both of them, and hit the comment shortcut ( CMD + / ).

// var dodgyVar1 = doSomethingDodgy('value'), goodVar1 = 'value' , goodVar2 = 'value' , // dodgyVar2 = doSomethingDodgy('value'); // Do some stuff here with those variables

Now in order to make the code valid, I need to go through the fiddly process of navigating to the beginning of line 2, adding a var statement there, an then to the end of line 3, and replacing the comma with a semi-colon. This doesn’t sound like much, but over time it becomes very tedious and was in fact the original reason for why I questioned my use of the Single Var Pattern.

Some arguments in favour

If you’re minifying your code, (which in 90% of situations is something you want to do) then you’ll be fine. Here’s some simple JavaScript I wrote:

function doit () { var foo = 'bar' ; var baz = 'qux' ; var adventure = 'time' ; foo = 'qux' ; baz = 'bar' ; adventure = 'stuff' ; return foo + baz + adventure ; } doit ();

And here’s the result produced by UglifyJS2:

function doit (){ var e = "bar" , t = "qux" , n = "time" ; return e = "qux" , t = "bar" , n = "stuff" , e + t + n } doit ();

As you can see, Uglify does the single var stuff for me, since in the doit scope there’s only one var statement. Not a problem. In fact, if you Single-Var-Pattern-ify my code, you’ll find the output to be exactly the same.

“It’s more readable”

Is it really? Shouldn’t one of the determining factors in how “readable” code is be how many people can understand what’s going on? I’ve seen many examples of code using SVP which assert that you should put the comma at the beginning of each line. If you ask me, this is not readable code for most people, especially JavaScript newbies or people not familiar with the Single Var Pattern:

var bar = thing . doTheThing ( 'a' ) , stuff = bar . makeMeAThing () , foo = thing . doTheOtherThing ( 'b' ) , baz = 'qux' ;

As my friend Jon said, “I’ve always found that for new people, the less syntax the better.” With Single Var, we’re introducing seemingly random comments and convention-based indentation. This is more syntax.

The “readability” thing is clearly a subjective matter, but I can’t get my head around the supposed benefits. To me it seems more simple and elegant to give each variable the honour of having its own var statement.

Conclusion

The Single Var Pattern has spread and been encouraged by JavaScript legends because it helps to prevent a large number of mistakes that people - both new and experienced with the language - make. Thus, it has become very popular as part of the average developer’s toolkit and “Gotcha!” library. Nevertheless, as with most fixes in programming, it introduces a few new problems.

Think about the cost/benefit. You may realise that by making one little change you can save yourself a lot of hassle, and may find yourself making far fewer mistakes.

That’s why I personally use the “Vars At The Top” pattern (or VATT, if you like), as opposed to the Single Var Pattern.

Further reading: Douglas Lee shares my opinion and writes about it. StackOverflow has a couple of good discussions about Disadvantages and Overdoing it. I was unable to find any posts in defence of the Single Var Pattern, only many which simply explained it and it’s usefulness for all the usual reasons, but I’d love to read a rebuttal.

P.S. Some people call the pattern I use the “multi-var pattern” but I don’t think it accurately describes what’s going on since if you had your var s scattered around the scope it could still be described as “multi-var”.

P.P.S. After publication I realised that Ben Alman actually wrote this blog post almost two years ago, pretty much header-for-header. Good man for getting there way before me, but I guess I’d expect that from the chap who brought us the brilliant jQuery BBQ and of course the infamous Star Wipe.

Thank you Lenny Martin, Jon Finerty and Charlotte Spencer for proofreading this post and suggesting some great edits.

Heckle me on Twitter @basicallydan.