for(var i = 0; i < 100; i++){
var foo = 5;
}
It works ...but is this bad?
I know I can declare var foo
outside, but why do that when I'm only going to use it in the loop?
for(var i = 0; i < 100; i++){
var foo = 5;
}
It works ...but is this bad?
I know I can declare var foo
outside, but why do that when I'm only going to use it in the loop?
Over time my personal style has grown into a preference for declaring variables where they "actually are" in the "mind" of the particular language I am working in. For JavaScript this means putting variable and function declarations in the positions where the language would hoist them anyway.
This is for clarity, precise communication, understanding, maintainability, to keep my own mental processes parallel with the processes of the language, just to mention a few good reasons.
So in this particular case, I would not put a var foo = 5;
declaration into the body of a for
loop, for the simple reason that it is not doing what it looks like it is doing, i.e., it is not in fact redeclaring/re-scoping the variable with every iteration. (Placing the var
declaration in the initialization portion of the for loop's header (initialization; condition; afterthought) would be more reasonable, and certainly the correct place to put it in languages that do have block-level variables, such as when JavaScript finishes adopting the let
-style declaration for block-level scope.)
Notes:
This practice may not seem "normal." My mind prefers to keep variables "close" to their use, and my current practice does not come naturally to the way my mind works. But as a programmer through the years, experiences with confusion, bad communication, misunderstanding, unmaintainable code impossible to unravel, etc., have more than justified the extra discipline that it takes me to follow this style of declaring variables in the locations corresponding to their actual scope, regardless of the language.
One extra benefit of this practice for me has been that it encourages me to keep my functions modular and reasonable in size.
Along the same lines, following this practice automatically helps keep my code organized in a sensible way. For instance, if putting my functions first causes there to be excessive functions before the code I am actually working on, and I therefore get irritated about having to go down two pages to edit my program, following this style automatically gives me incentive to organize my code into an appropriate structure of distinct files.
P.S. One could bring up a point that some functions are so long that this practice makes variable declarations end up pages away from where they are used. Yes, I have seen code where that is true, and perhaps even code where that cannot be helped. Yet I can't help observing the parallel that is equally true for authors of prose as it is for computer programmers. As skill level grows, the lengths of authors' sentences (and sizes of programmers' functions) tend to grow, and then as the skill level continues to grow yet higher, the lengths of sentences (and sizes of programmer's functions) tend to shorten once more.
It is bad because it gives the false impression that i
and foo
are local variables.
for(var i = 0; i < 100; i++){
var foo = 5;
}
foo; // 5
This might not be a problem with simple code, but if you use closures it becomes apparent that there is only one foo
:
var counters = [];
for (var i = 0; i < 100; i++) {
var foo = 5;
counters.push(function() { foo++; return foo; });
}
counters[0](); // 6
counters[0](); // 7
counters[1](); // 8 (!)
To create foo
in a different scope a function needs to be introduced:
var counters = [];
for (var i = 0; i < 100; i++) {
(function() {
var foo = 5;
counters.push(function() { foo++; return foo; });
})();
}
counters[0](); // 6
counters[0](); // 7
counters[1](); // 6
Here is a real-life example of things going wrong due to this: setTimeout in for-loop does not print consecutive values
Since JavaScript 1.7 you can use the let
keyword (see MDN) to create true local variables.