Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping For in loops with if statements in Javascript -- looping over arrays

JSLint keeps complaining about things like this

var myArray = [1, 2, 3];
for (var value in myArray)
{
   // BLAH
}

Saying that I should wrap it in an if statement. I realize you need to wrap it if you are looping over an object's properties, but here what should I put in the if statement to do the correct filtering.

Additionally when I do something like

for (var i = 0; i < 10; i++)
{
   // foo
}

for (var i =0; i < 20; i++)
{
   // bar
}

It complains that i has already been defined. How do I prevent this other than using different variable names?

like image 573
DevDevDev Avatar asked Oct 26 '09 18:10

DevDevDev


People also ask

Can we use for in loop for array in JavaScript?

A for loop can be used to access every element of an array. The array begins at zero, and the array property length is used to set the loop end.

How do you iterate through an array in a for loop?

For Loop to Traverse Arrays. We can use iteration with a for loop to visit each element of an array. This is called traversing the array. Just start the index at 0 and loop while the index is less than the length of the array.

Which loop is used to iterate over arrays and strings?

The for..of loop in JavaScript allows you to iterate over iterable objects (arrays, sets, maps, strings etc).

Which looping construct will iterate over the values of an array?

The foreach loop works only on arrays, and is used to loop through each key/value pair in an array.


3 Answers

JSLint whinges about a lot that's not really harmful. In this case it's right to complain about for...in, because that's the wrong construct to loop over an Array.

This is because you will get not only the numeric keys, but also any other arbitrary properties that have been added to the array or its Array.prototype. The latter typically comes from extension utility functions added by frameworks.

Whilst you can defeat that case with hasOwnProperty to check it's not a prototype member, it's uglier than just doing it the proper way with for (var i= 0...) so why bother.

Also, with for...in you won't necessarily get the items in numerical order as you might expect.

It complains that i has already been defined. How do I prevent this other than using different variable names?

Yeah, you can ignore that one.

It wants you to remove the var from the second for (i..., because declaring a variable twice in the same scope doesn't do anything. However I would recommend leaving the var there because it doesn't do any harm, and if you move the loop to another block you don't want it to be suddenly scribbling on globals.

like image 163
bobince Avatar answered Nov 02 '22 23:11

bobince


Really, you don't have to listen to jslint. But if you really want to just pass (which is nice) you might do:

var myArray = [1, 2, 3];
for (var value in myArray)
{
  if (myArray.hasOwnProperty(value)) {
    // BLAH
  }
}

For the second part, you either have to put them in functions or use different variables. The other solution would be to just use i instead of var i the second time, because it's already defined...

like image 32
Alex Sexton Avatar answered Nov 02 '22 23:11

Alex Sexton


If you look at the JSLint docs you'll find a link explaining the rationale behind filtering for-in loops: basically, it's to avoid tripping over any enumerable properties that have been added to the object's prototype. (Although you shouldn't use for-in to iterate over an array anyway.)

In the second case you are declaring the variable twice: variables have function scope (or global scope) in JavaScript. Douglas Crockford, and therefore JSLint, argues that it is better to declare the variable only once for the scope in which it resides:

var i;

for (i = 0; i < 10; i++)
{
   // foo
}

for (i =0; i < 20; i++)
{
   // bar
}
like image 26
NickFitz Avatar answered Nov 03 '22 01:11

NickFitz