Skip to content

Instantly share code, notes, and snippets.

@jbreckmckye
Created January 25, 2017 10:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbreckmckye/867be097f76cd113741a25779e1ee3fe to your computer and use it in GitHub Desktop.
Save jbreckmckye/867be097f76cd113741a25779e1ee3fe to your computer and use it in GitHub Desktop.
Get rid of that stupid single-var-declaration rule, once and for all

I don't like the single-var rule.

It annoys me for several reasons.

As a declaration grows, it becomes ambiguous

Here's a slice of code. What does it signify?

        peter: payPeter().toRob('paul'),
        simon: says(new Sayer()),
        alice: coop(3).r
    },
    alpha = new Beta(config),
    callback = new Maybe(fn).lift(iterable),
    self = this
    resolver = onError => {
        try {
            callback(self);
        } catch (e) {
             onError(e);
        }
    },
    bonus = {

Well, you know it's a set of variables, because you guess as much from the context. It's not exactly obvious, though. At a glance, am I looking at variables or the fields of an object? In very large files it's tough to say. And are these declared with var, let or const? This difference matters in ES6.

This style also buries an error - the code will leak a global variable that it wouldn't if everything was prefixed with var.

Most debuggers can't step over the individual declarations

Most debuggers will treat code like var x = a, y = b, ... = z; as a single line, and won't allow the developer to step over each individual assignment. This behaviour has changed in Chrome recently, but many other devtools environments will still treat the var operation as a single step.

Variables are declared out of context

One nice thing about free vars is that we can create them at the exact moment they are needed:

for (let i = 0; i < y; i++) {...}

This makes them a little easier to name. It also makes it easy to delete variables as soon as they're no longer needed.

It's awkward to format

Especially when using const. Do we indent successive vars using a single tab (easy to type, but looks ugly), or do we manually align each var with spaces?

const a = 12,
    b = 13,
    c = 14;

Changes add noise to pull requests

Every time I add a variable to a function, I have to chop and change the position of a semicolon. PRs look more noisy than they need to be:

>>>
  y = 25;
===
  y = 25,
  z = 26;
<<<

It's just not necessary any more

The single-var rule was popularised by Douglas Crockford, who believed it was necessary to protect developers from the curious scoping behaviour of var. In most C-like languages, variables are block scoped - but in JS, they're scoped to the function.

For instance, in the following loop, the iterator i exists and can be read outside the loop. This is a surprise to a developer coming from most other languages:

for (var i = 0; i < 10; i++) {}
console.log(i); // prints 10!

This wouldn't work in C++, for instance:

#include <iostream>

int main()
{
  for(int i=0; i<10; ++i) {}
  std::cout << i;
}

// COMPILE ERROR
// In function 'int main()':
// 7:16: error: 'i' was not declared in this scope

Because a C++ developer might assume JavaScript developers are block scoped too, putting all the vars at the top of the function seemed like a pragmatic style that would ensure such a programmer would never 'misread' the scope and longevity of a var.

And that's great. But we don't live in the 90s any more.

image

I wish we did - the music was better and you could buy houses - but the world has changed. Grunge is over. Side partings are no longer cool. Most importantly, we have ES6, and that gives us let and const, both of which have 'block scoping' (like C), as opposed to the 'function scoping' of var:

for (let i = 0; i < 10; ++i) {};
console.log(i); // ReferenceError: i is not defined

So. The single var rule is not needed, not wanted (by me) and not helpful. I propose we get rid of it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment