What is the JavaScript variable scope in a switch

2019-04-21 06:58发布

问题:

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?

回答1:

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


回答2:

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.



回答3:

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