简体   繁体   中英

Best practice for declaring empty javascript variables

Is there something like a best practise when it comes to declaring variables in javascript before assigning a value to them? Sometimes it's necesary for scope reasons, but what if scope doesn't matter?

// Declare first
(function() {
    var foo = 'bar',
        a = 500,
        b = 300,
        c;

    // Some things get done here with a and b before c can use them...

    c = a * b;    

    // c is now ready to use...
    doSomething(c);
}());

// Declare when needed
(function() {
    var foo = 'bar',
        a = 500,
        b = 300;

    // Some things get done here with a and b before c can use them...

    var c = a * b; 

    // c is now ready to use...
    doSomething(c);
}());

And I'm also wondering what's best practise for something similar with object literals:

// Add property with null assigned to it
var myObj = {
    foo: null,

    doSomething: function() {
        this.foo = 'bar';
    }
};

// Property gets added when value is set
var myObj = {
    doSomething: function() {
        this.foo = 'bar';
    }
};

It is mostly a matter of style.

As var declarations are automatically hoisted up to the top of the scope, it makes sense to place them at top of their scope so that you can read the code closer to how the interpreter will execute it.

Declaring variables at the top of their scope is Crockford's recommendation . And it does make sense as it clears up some common misconceptions.

For example:

for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 0);
}

Since var has function scope, all iterations (and functions inside of them) refer to the same i . As all three timed functions will execute after the loop ends, the snippet above logs 3 three times.

Now for those with block scoping experience, the above behavior is not very clear. Rewriting the snippet:

var i;
for (i = 0; i < 3; i++) {
    // ...
}

Now, i is declared in the global scope, exactly as the previous snippet. However, this one is much more clear on that.


Another misconception:

(function() {
    if (true) {
        var foo = 1;
    } else {
        var foo = 1;
    }
}());

Again, in block-scoped languages¹ the above is perfectly valid. However, as var declarations are hoisted up to top of the current function scope at parse time, the above is equivalent to:

(function() {
    var foo;
    var foo;
    if (true) {
        foo = 1;
    } else {
        foo = 1;
    }
}());

The variable is declared twice. Most browsers will just ignore the second declaration and the code will "work", but static code analysis tools such as JSHint will yell at you.

You can rewrite it with only one declaration and it is perfectly valid:

(function() {
    if (true) {
        var foo = 1;
    } else {
        foo = 1;
    }
}());

But OCD-like coders like me will find it rather ugly. So again, declaring at top of the scope:

(function() {
    var foo;
    if (true) {
        foo = 1;
    } else {
        foo = 1;
    }
}());

Looks much more tidier.


Again, it is mostly a matter of style. Personally, if I have a giant function, I hate to scroll all the way up just to check whether a variable is already declared and adding it to the list. In that case, I may just add a couple of var declarations in the middle of the function (against Crockford's recommendation) which I personally find easier to read and maintain.

As it is a matter of style, just make sure to keep your code the most maintainable and concise possible.


In the other side of the coin, I'll admit that, personally, I've started and mostly used var declarations when the variable is firstly used. This is an aspect of the language and you can use it this way without problem.

But I will also admit that, if I had followed Crockford's recommendations from the start, I'd have had many less headaches (as with the misconceptions shown above) and would have grasped JavaScript's function scoping aspect much faster.


¹ Note that JS 1.7 introduced block-scoped variables through let , but it is not widely supported yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM