Yahel
Yahel

Reputation: 37305

Proper for/in variable declaration

What is the proper syntax for declaring the loop-specific variable in a for/in loop?

The first two both seem to work (and don't raise any flags in Google Closure Compiler), but only the third one passes Crockford's JS Lint. I am reluctant to use it, mostly because it is not compact.

JSLint complains that either val is a bad variable (when I don't add var), or that the declaration should be moved.

Are there any drawbacks to the first or second option? What should I be using? (Examples assume str is a declared string and vals is a declared object)

1. No declaration:

for(val in vals)
{
    if(vals.hasOwnProperty(val))
    {
        str += val;
    }
}

2. In 'for' var declaration:

for(var val in vals)
{
    if(vals.hasOwnProperty(val))
    {
        str += val;
    }
}

3. Outside the loop var declaration:

var val;
for(val in vals)
{
    if(vals.hasOwnProperty(val))
    {
        str += val;
    }
}

Upvotes: 4

Views: 518

Answers (3)

Šime Vidas
Šime Vidas

Reputation: 185893

1. Option

The val variable becomes an implicit global variable. Implicit global variables are 100% bad and should be avoided.

2. and 3. Option

The val variable becomes a variable of the containing scope. If your code is inside a function, then the val variable becomes a local variable of that function. Both options are equivalent. (I prefer the 2. option.)

JSLint will throw because Crockford's idea is to always declare all variables at the top of the code. This makes more sense for code that is larger in size (like > 100 lines) - in that case you may consider to move the declarations out of the for and for-in statements, and put them at the top of the code. That way you will have a good overview of all the local variables.

Upvotes: 1

James Sumners
James Sumners

Reputation: 14777

In addition to cwolves reasoning behind the variable declaration, JSLint is also considering variable hoisting.

That being said, I prefer option #2 when writing for loops. I do define the rest of my variables at the top of the function, though. So I like:

function foo(a) {
  var b, c = {d: "e", f: "g"};

  for (var i = 0, j = a.length; i < j; i += 1) {
    ...
  }

  for (var h in c) {
    if (c.hasOwnProperty(h)) {
      ...
    }
  }      
}

Upvotes: 1

user578895
user578895

Reputation:

Feel free to ignore JSLint. It's a guideline more than anything. The 2nd and 3rd are functionally identical, feel free to use either (I use the 2nd). The first exposes a global 'val' variable, so don't do it :)

FYI the reasoning behind the 3rd is that inline variable declarations are much harder to spot/find than:

var a, b, c, d, e;

at the top of a function.

Upvotes: 3

Related Questions