views:

91

answers:

3

While creating JavaScript with ASP.NET MVC I noticed several scope warnings and realized that I am missing something with understanding the variable scope inside the switch / case statement.

Warning: 'i' is already defined referring to case b and case c

My code looks similar to this:

switch(element) {
  case 'a':
   for(var i=0; i < count; i++){
    do something
   }
   break;

  case 'b':
   for(var i=0; i < count; i++){
    do something
   }
   break;

  case 'c':
   for(var i=0; i < count; i++){
    do something
   }
   break;
}

I thought scope ended with each break statement but it seems that scope does not end until the end of the switch/case. Is scope for the entire switch/case?

+7  A: 

Javascript does not use block scope.

Therefore, all local variables are in scope throughout the entire function in which they were declared.

However, in your particular case, there is no C-like language (that I know of) in which each case statement forms an independent scope.
For example, the following C# code will not compile:

switch(someVar) {
    case 1:
        int a;
        break;
    case 2:
        int a;        //'a' is already defined
        break;
}
SLaks
Yes. I must be falling asleep on this one because at first glance it seemed right. But joy for compiler warnings to let me know when I've fallen asleep. Thank You for such a great answer.
Todd Moses
A: 

Even if javascript had block scope, there is the fall-through feature which kinda disqualifies the notion of having a scope per case...

npup
+1  A: 

Is scope for the entire switch/case?

No, it's for the entire containing function, or global scope if you're outside a function.

(There are a obscure few cases in which JavaScript introduces extra scope, but that's about it.)

Warning: 'i' is already defined

I don't really agree with this being a warning. I would prefer to leave the code as it is, with the blocks' independent uses of the variable i.

What it wants you to do is remove the var from all but the first declaration, or maybe add var i before the switch and remove var from all the for​s. But now those blocks don't stand alone, and a quick cut-and-paste (for, say, refactoring the switch into separate function​s) leaves you with loops referencing an i that hasn't been declared var. This is an accidental global, and it's a horrible JS trap which can be a real pain to debug.

JSLint makes the same complaint. I would typically ignore it. It does no harm to declare a variable var twice in one block.

bobince
Yes I know it works. I just do not like to have warnings in production code. But a talk here in the office about it revealed that jQuery does the same thing. So I may leave it. Thank you for the good answer.
Todd Moses