3
var i,j;
for (i=0; i<30; i++) {
    for (j=0; j<10; j++) {
        // do something
    }
}

versus

for (var i=0; i<30; i++) {
    for (var j=0; j<10; j++) {
        // do something
    }
}

The second way creates and destroys j 30 times, due to the scope logic of javascript? I prefer to use the first way, but I don't really know if there's a difference. Is there?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Rodrigo
  • 4,706
  • 6
  • 51
  • 94
  • 4
    The `var` gets hoisted. Personally I think the first is cleaner, but it's equivalent. – Paul S. Jan 14 '15 at 14:13
  • 2
    The key is that you're mistaken about the "scope logic of javascript", `for` statements don't have any special scope, functions do. – adeneo Jan 14 '15 at 14:24
  • `The second way creates and destroys j 30 times` It would be the case if using `for (let j=0; j<10; j++)` – A. Wolff Jan 19 '15 at 19:14

3 Answers3

14

No. JavaScript hoists the variable declarations. So, all the variable declarations go to the top of the function in which they are defined in. So, all these variables are created only once and their values are changed every time in the loop.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • don't mind me interrupt,but for the second example does the variables that are hoisted at the top gets overwritten every time as it starts with var keyword every time? – AL-zami Jan 14 '15 at 14:40
  • @al-Zami No. It will only be overwritten if there's an assignment. Javascript doesn't really have automatic initialization. – Luaan Jan 14 '15 at 16:20
6

Both answers by @thefourtheye and @Remigius Kijok are correct. Whenever variables are declared and initialized within functions (or within the global scope), the declaration gets hoisted to the top of that scope.

You can see this for yourself by wrapping either of the for loops you have within a function and then executing the function in your browser. Specifically, by setting a break point at that top of the function, you'll be able to see that all the variables are declared and initialized with the value undefined prior to the function executing.

var loopy = function () {
  for (var i = 0; i < 5; i += 1) {
    for (var j = 0; j < 3; j += 1) {
      console.log('i is ' + i + ' and j is ' + j);
    }
  }
};

loopy(); // place break point here

Variable hoisting

As you can see in the photo, I'm using Chrome's dev tool and placing a break point on the execution of loopy(). After entering the function, but prior to executing any of the for loops, the variables i and j are both declared but undefined.

wmock
  • 5,382
  • 4
  • 40
  • 62
  • Hmm, the dev tools aren't really the best way to demonstrate this, as the results will depend a lot on how the compiler optimizes the code (see [my answer here](http://stackoverflow.com/questions/21917271/my-function-somehow-doesn-t-have-access-to-its-parent-closure-is-missing-varia/21918024#21918024)). You can however, demostrate this by showing that `function(){j = 0; console.log(j); if (false) { var j = 1; } console.log(j)}` prints `0 0` -- i.e. even though the statement with the `var` was never evaluated, `j` still exists and can hold a value. – p.s.w.g Jan 14 '15 at 22:38
  • If you look at the scope variables section, you can clearly see that prior to executing any lines of code in the function, the `i` and `j` variables are `undefined`. – wmock Jan 15 '15 at 02:54
5

Your both versions are equal. There is no difference. The variable j will not be created and destroyed 30 times.

Remigius Kijok
  • 215
  • 2
  • 8