views:

199

answers:

3

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?

+3  A: 

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...

Alex Sexton
+4  A: 

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.

bobince
+3  A: 

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
}
NickFitz