What is the most idiomatic way to handle variables declared in multiple for loops? [closed]

StackOverflow https://stackoverflow.com/questions/21125441

  •  28-09-2022
  •  | 
  •  

Question

JavaScript only has function scope. Thus, variables declared in for loops are visible for the entire function.

For example,

function foo() {
    for(var i = 0; i < n; i++) {
        // Do something
    }
    // i is still in scope here
}

When we have multiple for-loops, this opens the question of how we handle the variables in these other for loops.

Do we use a different variable?

for(var i = 0; i < n; i++) { }
for(var j = 0; j < n; j++) { }

Or do we use the same variable but just assign a value (instead of declaring it)?

for(var i = 0; i < n; i++) { }
for(i = 0; i < n; i++) { }

Or declare i outside of the loops?

var i;
for(i = 0; i < n; i++) { }
for(i = 0; i < n; i++) { }

Or redeclare i?

for(var i = 0; i < n; i++) { }
for(var i = 0; i < n; i++) { }

All of these work (or at least they do on the latest versions of my browsers). JSHint doesn't like the last approach, though.

Is there an approach which is most idiomatic or otherwise preferable?

Was it helpful?

Solution

It really depends on who you're coding for. If you're coding for a company or contributing to a library you of course follow their style guide. I've seen all of these (expect the last) used in libraries. If you like the Douglas Crockford style you'll go with the second to last and place all your variables at the top of function scope (or jslint will shout at you).

Taking an example from the jQuery style guide:

This is considered Good style

var i = 0;

if ( condition ) {
    doSomething();
}

while ( !condition ) {
    iterating++;
}

for ( ; i < 100; i++ ) {
    object[ array[ i ] ] = someFn( i );
}

While this is poor style:

// Bad
if(condition) doSomething();
while(!condition) iterating++;
for(var i=0;i<100;i++) object[array[i]] = someFn(i);

Anyway, because this is style I'm going to reference how several libraries write their for each loops:

If your code is going to be minimized before you release it, it will not matter as minifiers will mangle it to pretty much the same end representation in the processing.

OTHER TIPS

Using different variables we have no problems.

Reusing and reassigning makes the code less readable, and if we remove the declaration at a later time, we risk assigning i to something outside of the function scope.

Declaring i outside the loops, we have no problems.

Redeclaring will be an issue if your lint tool, IDE, etc complain.

So I would argue for the first or third option. If number of variables is a concern using the first option, then you are may be in need of a refactoring.

Another take that answers the question in a different way.

A function with multiple loops makes me suspicious because:

  1. It may be doing too much and should be decomposed anyway, and
  2. It may be better to write it more functionally and eliminate the index altogether (it's available in some each-/map-y functions anyway)

Another approach is to use iterator functions. For example, in modern browsers an Array will have a forEach method:

var items = ["one", "two", "three"];
var things = ["hello", "goodbye"];

items.forEach(function (item, index) {
   // Do stuff
});

things.forEach(function (item, index) {
   // Do stuff
});

If you're using older browsers (or custom collections), you can make your own iterator like this:

Array.prototype.forEach = function(callback) {       
   for(var i = 0; i < this.length; i++) {
      callback.apply(this, [this[i], i, this]);
   }
};

For more information see: Array.prototype.forEach()

Any variables declared within a function are interpreted as being declared at the beginning of the function. Doug Crockford argues that you should declare all of your variables at the first line of every function.

doSomething = function() {
   var i, ... other variables ...;
   ...
   for (i = 0; i < x; i += 1) {
      ...
   }
   ...
   for (i = 0; i < x; i += 1) {
      ...
   }
}

This way the code reads in the same way it will be parsed by the javascript engine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top