The problem with declaring with var
in the loop header is that it's deceptive. It looks like you're declaring a variable whose scope is limited to the for
loop, when it actually exists everywhere within the function - including before the declaration:
var i = 1;
function foo() {
console.log(i); // 'undefined'
for (var i=1; i<100; ++i) {
}
}
Even though the console.log
call occurs before the declaration of the local i
, it is still in scope for it because it's inside the same function. So the local i
, which has not yet had any value assigned to it, is what gets passed to log
. This can be surprising; it's certainly not obvious to anyone who's not familiar with Javascript scoping rules.
Starting with ECMAScript 2015, there is a better way to declare variables: let
. Variables declared with let
are local to the block containing them, not the entire function. So this version of the above code will print 1
as intended:
let i=1; // could use var here; no practical difference at outermost scope
function foo() {
console.log(i); // 1
for (let i=1; i<100; ++i) {
}
}
So best practice in modern Javascript is to declare variables with let
instead of var
. However, if you are stuck with a pre-ECMAScript 2015 implementation, it's a little less confusing to declare all variables at the top of the function, rather than waiting till first use.