JavaScript loop variable scope

67,766

Solution 1

See the MDN for the "initialization parameters" of a for-loop:

An expression (including assignment expressions) or variable declaration. Typically used to initialize a counter variable. This expression may optionally declare new variables with the var keyword. These variables are not local to the loop, i.e. they are in the same scope the for loop is in. The result of this expression is discarded.

Solution 2

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/

Solution 3

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.

Solution 4

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

Share:
67,766
BlackBox
Author by

BlackBox

A Computer Science graduate and Software Engineer from North Wales, UK.

Updated on May 06, 2020

Comments

  • BlackBox
    BlackBox almost 4 years

    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.

  • Mike Tronic
    Mike Tronic almost 8 years
    update your answer with more info. the spec is official. thanks
  • James Dewes
    James Dewes over 5 years
    This is true of var, but needs to now consider the let keyword