Reputation: 2233
Just a quick question about the scoping of JavaScript variables.
Why does the alert()
function print the value of i
instead of returning undefined
?
$(document).ready(function () {
for(var i = 0; i < 10; i += 1){
}
alert("What is 'i'? " + i);
});
I'm fairly new to JS, and in nearly all other languages I've dabbled, a declaration in the scope of the for loop would contain the value to that said loop, but not in this case, why?
i.e. What is 'i'? 10'
is printed.
Upvotes: 69
Views: 76927
Reputation: 23580
See the MDN for the "initialization" of a for
-loop:
An expression (including assignment expressions) or variable declaration evaluated once before the loop begins. Typically used to initialize a counter variable. This expression may optionally declare new variables with
var
orlet
keywords. Variables declared withvar
are not local to the loop, i.e. they are in the same scope the for loop is in. Variables declared withlet
are local to the statement. The result of this expression is discarded.
Upvotes: 75
Reputation:
JavaScript didn't have block scope until const
and let
were introduced, just var
which is function scoped. Since the initialization of i
is within one function, that variable is accessible anywhere else in that same function.
From MDN:
Important: JavaScript does not have block scope. Variables introduced with a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. Although "standalone" blocks are valid syntax, you do not want to use standalone blocks in JavaScript, because they don't do what you think they do, if you think they do anything like such blocks in C or Java.
Upvotes: 62
Reputation: 935
The javascript folks are trying to fix this!
EcmaScript6 (aka EcmaScript 2015) is the latest version of javascript that was passed last summer and browsers are just starting to support its features.
One of those features is block-scope local variables with the "let" expression. As of right now (April 2016), most of the current versions of the major browsers support this except Safari. Few mobile browsers support this.
You can read more about it here (in particular, see the section "let-scoped variables in for loops"): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
You can check current browser support here (look for the row Bindings -> let): https://kangax.github.io/compat-table/es6/
Upvotes: 16
Reputation: 91
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
it is not correct to state that the above creates a global variable i
. I believe you should always use var
to declare variables (unless you are intentionally wanting a 'property' rather than a 'variable' -which is pretty unlikely in 99.99% of JS coding scenarios ...)
Omitting var
when assigning an initial value to i
isn't creating a local or even a global variable, it is creating a property i
for the global object (which may seem/behave mostly like a global variable - but they have some subtle differences).
better would be:
var i;
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
now the loop is using a global variable i
(or function local variable i
, if this code appears in a function)
see more about this at what is function of the var keyword and variables vs. properties in Javascript
-- note, what is a little confusing is that you can re-declare a variable, for example in a second loop
for(var i=0; i<9; i++){
document.write('i = ' + i + '<br>');
}
for(var i=0; i<9; i++){
document.write('i = ' + i + '<br>');
}
this seems to be valid (no errors when I test). It seems that you CAN re-declare variables in JavaScript - but it probably isn't every a good idea, unless a special case - see this related question mentioning how [Google Analytics makes use of the 'safe' redeclaration of a variable] (Redeclaring a javascript variable)
there is some discussion about re-declaring variables in JS (and also loop variables like i
) in this related SO question: declare variables inside or outside the loop
There is event a JavaScript pattern for single declaration of variables
Upvotes: 9
Reputation: 3698
Unlike other languages (for example: Java, C++, C), JavaScript doesn't support block scope. Once you declare a variable in a loop or in a function it's scope is within the function body if you do
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
here your i
becomes a global variable and j
become local to the function or script in which the loop is.
Upvotes: 11