Что такое область переменных JavaScript в инструкции switch/case?

При создании JavaScript с помощью ASP.NET MVC я заметил несколько предупреждений о масштабах и понял, что мне что-то не хватает, понимая область переменной внутри оператора switch/case.

Предупреждение: "i" уже определено, ссылаясь на случай b и case c

Мой код выглядит примерно так:

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

Я думал, что область действия заканчивается каждым оператором break, но кажется, что область действия не заканчивается до конца коммутатора/случая. Является ли область для всего коммутатора/случая?

Ответ 1

Javascript не использует область блока.

Поэтому все локальные переменные находятся в области видимости по всей функции, в которой они были объявлены.

Однако в вашем конкретном случае нет C-подобного языка (который я знаю), в котором каждый оператор case формирует независимую область.
Например, следующий код С# не будет компилироваться:

switch(someVar) {
    case 1:
        int a;
        break;
    case 2:
        int a;        //'a' is already defined
        break;
}

Ответ 2

Является ли область для всего переключателя/случая?

Нет, это для всей содержащейся функции или глобальной области видимости, если вы вне функции.

(Есть несколько неясных случаев, в которых JavaScript вводит дополнительную область видимости, но об этом.)

Предупреждение: "i" уже определено

Я не согласен с тем, что это предупреждение. Я бы предпочел оставить код так, как есть, с независимыми использованием блоков переменной i.

Что вам нужно сделать, это удалить var из всех, кроме первого объявления, или добавить var i перед коммутатором и удалить var из всех for s. Но теперь эти блоки не стоят наедине, а быстрый вырез и вставка (например, рефакторинг switch в отдельный function s) оставляет вас с петлями, ссылающимися на i, который не был объявлен var. Это случайный глобальный, и это ужасная JS-ловушка, которая может быть настоящей болью для отладки.

JSLint делает такую ​​же жалобу. Обычно я игнорирую это. Не вредно объявлять переменную var дважды в одном блоке.

Ответ 3

Даже если у javascript была область видимости блока, есть сквозная функция, которая как бы дисквалифицирует понятие наличия области видимости на case...