Зачем Javascript `if ... else if` не заканчиваться` else`? - PullRequest
8 голосов
/ 09 ноября 2011

Вот фрагмент кода JavaScript из учебника, с которым я работал.Я не понимаю, почему это не заканчивается заключительным предложением else;Я думал, что это было правилом.

var curScene = 0;

function changeScene(decision) {
  var message = "";

  if(curScene == 1) {
    message = " welcome";
  } else if (curScene == 2) {
    message = " this is scene two";
  } else if (curScene == 3) {
    message = " this is scene three";
  }

  document.getElementById("sceneimg").src = "scene" + curScene + ".png";

  if(message != ""){
    alert(message);
  }
}

Ответы [ 8 ]

14 голосов
/ 09 ноября 2011

Я думал, что это всегда должно заканчиваться "иным"?

Вы ошибаетесь.Блок else является необязательным.Вы можете иметь if без else.

5 голосов
/ 09 ноября 2011

По той же причине, по которой вы можете иметь только один, если:

if( /*condition*/ ) {
    //some code
}

//other stuff
3 голосов
/ 09 ноября 2011

Рассмотрим 3 сценария
Сценарий 1: Логическое условие

if (condition) {}
else {}

Указание условия как-бы иначе было бы избыточным, и для читателя действительно очевидно, что делает код. В этом случае нет аргумента для использования else.

Сценарий 2: Бесконечные состояния

Здесь мы заинтересованы в проверке условий A и B (и т. Д.), И нас может интересовать или не интересоваться тем, что происходит, если ни одно из них не выполняется:

if (conditionA) {}
else if (conditionB) {}
else {} // this might be missing as it is in your case

Важным моментом здесь является то, что не существует конечного числа взаимоисключающих состояний, например: условие A может быть num % 2 == 0, а условие B может быть num % 3 == 0.

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

Сценарий 3: Finite states

Это золотая середина между первыми двумя случаями: число состояний конечно, но больше двух. Тестирование значений перечислимого типа является типичным примером:

if (var == CONSTANT_FOO) {}
else if (var == CONSTANT_BAR) {} // either this,
else {} // or this might be missing

В таких случаях использование переключателя, вероятно, лучше, потому что он сразу сообщает читателю, что число состояний конечно, и дает сильный намек на то, где может быть найден список всех возможных состояний (в этом примере начинающиеся константы с CONSTANT_). Моими личными критериями является количество состояний, с которыми я проверяю: если это только одно (нет больше, если), я буду использовать if; в противном случае, переключатель. В любом случае я не буду писать еще, если в этом сценарии.

Добавление else как пустой блок catch-errors

Это напрямую связано со сценарием № 2 выше. Если возможные состояния не являются конечными и известны во время компиляции, вы не можете сказать, что «в любом другом случае» означает, что произошла ошибка. Учитывая, что в сценарии № 2 переключение будет более естественным, я чувствую, что использование этого способа имеет неприятный запах кода.

Вместо этого используйте переключатель с веткой по умолчанию. Он сообщит ваши намерения гораздо яснее:

switch(direction) {
    case 'up': break;
    case 'down': break;
    default: // put error handling here if you want
}

Это может быть немного более многословно, но читателю ясно, как должен функционировать код. На мой взгляд, пустой блок else будет выглядеть неестественно и загадочно.

2 голосов
/ 09 ноября 2011

Не обязательно, по той же причине, if само по себе не требует else.

Обычно это хорошая идея иметь такую ​​ситуацию, как своего рода «ловушку», но приведенный выше код можно записать так:

switch(curScene) {
    case 1: message = " welcome"; break;
    case 2: message = " this is scene two"; break;
    case 3: message = " this is scene three"; break;
}

В приведенном выше коде я также мог бы добавить:

    default: message = " invalid curScene value"; break;

Но это совершенно необязательно. От того, насколько надежна переменная curScene, зависит, буду ли я лично добавлять ее.

0 голосов
/ 23 июля 2016

Отсутствие предложения else нормально в синтаксическом смысле. Документация MDN По сути, второй if становится телом остального, см. Раздел о том, «как бы выглядело, если бы вложенность была правильно отступа».

Что касается того, является ли это плохой практикой, я думаю, что это зависит от намерения.Не определяя явно последнее предложение else, вы можете получить ошибку, из-за которой возникает условие, которое вы не охватили.Подумайте об этом:

if(myVariable > 0) {
   doSomething();
} else if(myVariable < 0) {
   doSomethingElse();
}

Ничего не произойдет, если myVariable равен 0. Было бы трудно увидеть, если вы просто просматривали код.Я бы сказал, что если вы столкнетесь с этим шаблоном, это будет запах кода, что-то может быть не так, но это может быть хорошо.

Одна и та же логика всегда может быть выражена с помощью вложенных операторов if.Я бы пошел с тем, что является более читабельным.

0 голосов
/ 16 марта 2013

изменить условие if для подтверждения ответа if (answer == 100) на if (answer === 100) сейчас работает нормально ...

0 голосов
/ 09 ноября 2011

else - это default case для оператора if. Если нет else, то, если ни одно из условий в случаях if или else if не выполнено, то устав if ничего не сделает.

Обычно рекомендуется использовать регистр по умолчанию, но во многих случаях это не нужно и, следовательно, исключается из кода.

В этом случае, если curScene был чем-то отличным от 1, 2, 3, то будет использоваться else, но поскольку в других случаях обработка не выполняется, кодер не включил else .

0 голосов
/ 09 ноября 2011

да, всегда есть else is VERY GOOD привычка (при использовании с if-elseif). иногда люди могут даже написать это:

if(curScene == 1) {
    message =" welcome";
else if (curScene == 2) {
    message = " this is scene two";
}
else if (curScene == 3) {
    message = " this is scene three";
} else {
    // empty.
}

сказать людям, что в остальном действительно нечего делать.

...