3. Ветвления
В программе решение, или ветвление, сводится к переходу в другую часть программы в зависимости от значения соответствующего выражения.
В JavaScript существует несколько типов ветвлений, наиболее важным из которых является if...else, осуществляющее выбор между двумя альтернативами. В инструкции ветвления if...else использование else не является обязательным. Для выбора одной из множества альтернатив используется инструкция ветвления switch(switch Statement), действие которого определяется набором значений соответствующей переменной. Кроме того, существует так называемая условная операция, используемая в некоторых особых ситуациях. Мы рассмотрим каждую из этих конструкций.
3.1 The if Statement/Инструкция if
3.3.1 Оператор if
Оператор if является наиболее простым из операторов ветвлений. Следующие примеры иллюстрируют применение оператора if.
Пример
'use strict';
var a = prompt('Введите значение a: ', '');
if ( a > 100 )
alert('Это число больше, чем 100');
За ключевым словом if следует условие ветвления, заключенное в круглые скобки. Оператор if (...) вычисляет и преобразует выражение в скобках к логическому типу.
Пример
'use strict';
var year = prompt('В каком году появилась спецификация ECMA-262 5.1?', '');
if (year != 2011)
alert( 'А вот и неправильно!' );
Оператор if («если») получает условие, в примере выше это year != 2011. Он вычисляет его, и если результат – true, то выполняет команду.
3.3.2 Несколько операторов в теле if
Если нужно выполнить более одной команды – они оформляются блоком кода в фигурных скобках:
Пример
'use strict';
if (year != 2011) {
alert( 'А вот..' );
alert( '..и неправильно!' );
}
Пример
'use strict';
var x = prompt('Введите число: ', '');
if (x > 100) {
alert('Число ', x);
alert('больше, чем 100');
}
Рекомендуется использовать фигурные скобки всегда, даже когда команда одна.
Это улучшает читаемость кода.
Синтаксис оператора if показан на рисунке:
3.3.3 Оператор if...else
Оператор if позволяет совершать действие в том случае, если выполняется некоторое условие. Если же условие не выполняется, никакого действия не выполняется. Однако, можно представить такую ситуацию, когда нам необходимо совершить одно действие в случае выполнения условия и другое действие в случае невыполнения этого условия. Здесь оказывается полезным ветвление if...else. Оно состоит из оператора if, за которым следует блок операторов, и ключевого слова else, за которым следует еще один блок операторов. Синтаксис ветвления показан на рисунке:
Пример
'use strict';
var a = prompt('Введите число: ', '');
if (a > 100)
alert('Это число больше, чем 100');
else
alert('Это число не больше, чем 100');
Пример
'use strict';
var year = prompt('Введите год появления стандарта ECMA-262 5.1', '');
if (year == 2011) {
alert( 'Да вы знаток!' );
} else {
alert( 'А вот и неправильно!' ); // любое значение, кроме 2011
}
В зависимости от истинности или ложности условия ветвления, программа выводит соответствующее сообщение.
3.3.4 Вложенные ветвления if...else
Возможно, вам приходилось видеть приключенческие игры, предназначенные для ранних версий MS DOS. Их суть заключалась в следующем: играющий двигал своего «героя» по воображаемому ландшафту и замкам среди волшебников, сокровищ и т. д., с помощью текстовых символов. Следующии пример, напоминает небольшую часть такой приключенческой игры.
Пример
'use strict';
var x = 10, y = 10, position = '';
alert('Введите \'end\' для выхода...');
if (position != 'end') {
alert('Ваши координаты: ' + x + ',' + y);
position = prompt('Выберите направление (n, s, e, w): ', '');
if (position == 'n') // движение на север
y--;
else
if (position == 's') // движение на юг
y++;
else
if (position == 'e') // движение на восток
x++;
else
if (position == 'w') // движение на запад
x--;
alert('Ваши координаты: ' + x + ',' + y);
}
Когда игра начинается, вы оказываетесь на бесплодном участке земли. Вы можете передвигаться на север, юг, запад и восток, а программа будет следить за вашими передвижениями и сообщать ваши текущие координаты. Начало движения находится в точке с координатами (10, 10). С вашим героем не будет происходить ничего интересного, куда бы он ни пошел; пустая земля простирается во всех направлениях, как видно на рисунке:
Для выхода из программы нужно ввести слово ‘end’.
Данная програма не являеться шедевром среди видеоигр, однако в ней демонстрируется применение вложенных ветвлений. Так, оператор if находится внутри оператора if...else, который, в свою очередь, также является частью ветвления if...else. Если первое условие не выполняется, то проверяется второе условие и т. д. до тех пор, пока не будут проверены все условия. Если какое-либо из условий выполняется, то изменяется соответствующая координата x или у, после чего программа выходит из всех вложенных ветвлений. Подобные вложенные группы ветвлений называются деревом ветвлений.
3.3.5 Конструкция else...if
Вложенные ветвления if...else выглядят несколько неуклюже и могут представлять трудность для восприятия, особенно если глубина вложенности больше или тело оператора if...else является блоком кода.
Пример
'use strict';
var x = 10, y = 10, position = '';
alert('Введите \'end\' для выхода...');
if (position != 'end') {
alert('Ваши координаты: ' + x + ',' + y);
position = prompt('Выберите направление (n, s, e, w): ', '');
if (position == 'n') { // движение на север
y--;
console.log('go north');
} else {
if (position == 's') { // движение на юг
y++;
console.log('go south');
} else {
if (position == 'e') { // движение на восток
x++;
console.log('go east');
} else {
if (position == 'w') { // движение на запад
x--;
console.log('go west');
}
}
}
}
alert('Ваши координаты: ' + x + ',' + y);
}
Существует еще один вариант записи этих же действий. Необходимо только немного изменить последовательность записи кода программы. В результате получим следующий пример:
Пример
'use strict';
var x = 10, y = 10, position = '';
alert('Введите \'end\' для выхода...');
if (position != 'end') {
alert('Ваши координаты: ' + x + ',' + y);
position = prompt('Выберите направление (n, s, e, w): ', '');
if (position == 'n') { // движение на север
y--;
console.log('go north');
} else if (position == 's') { // движение на юг
y++;
console.log('go south');
} else if (position == 'e') { // движение на восток
x++;
console.log('go east');
} else if (position == 'w') { // движение на запад
x--;
console.log('go west');
}
}
alert('Ваши координаты: ' + x + ',' + y);
У вас может создаться впечатление, что мы использовали новый вид ветвления else...if. Программа последовательно исполняет блоки else...if до тех пор, пока не выполнится хотя бы одно из проверяемых условий. Затем исполняется соответствующий оператор и производится выход из ветвлений. Такой способ представления вложенных ветвлений гораздо проще и удобнее для понимания, чем обычная последовательность конструкций if...else.
3.3.6 Условная операция, тернарный оператор(Conditional Operator)
В этом разделе пойдет разговор об операции, выполняющей несколько нетипичные действия. Существует распространенная в программировании ситуация: переменной необходимо присвоить одно значение в случае выполнения некоторого условия и другое значение в случае невыполнения этого условия. В следующем примере переменной min присваивается наименьшее из значений alpha и beta с помощью конструкции if...else:
Пример
'use strict';
var alpha = 1, beta = 2;
if (alpha < beta) {
min = alpha;
} else {
min = beta;
}
Подобные действия на практике оказались настолько распространенными, что была специально разработана условная операция, выполняющая эти действия. Эта операция записывается с помощью двух знаков и использует три операнда. Она является единственной операцией в JavaScript, использующей более двух операндов. С помощью условной операции можно записать предыдущий фрагмент следующим образом:
Пример
'use strict';
var alpha = 1, beta = 2;
min = (alpha < beta) ? alpha : beta;
Правая часть оператора представляет собой условное выражение:
'use strict';
(alpha < beta) ? alpha : beta; // условное выражение
Если значение проверяемого условия истинно, то условное выражение становится равным значению alpha; в противном случае оно становится равным beta. Скобки вокруг проверяемого условия не обязательны, но их довольно часто употребляют для того, чтобы упростить визуальное восприятие этого оператора.
условие ? значение1 : значение2;
На рисунке показан синтаксис оператора условия:
3.3.7 Несколько условных операторов
Последовательность операторов '?' позволяет вернуть значение в зависимости не от одного условия, а от нескольких.
Пример
'use strict';
var age = prompt('Ваш возраст?', 18);
var message = (age < 3) ? 'Здравствуй, малыш!' :
(age < 18) ? 'Привет!' :
(age < 100) ? 'Здравствуйте!' :
'Какой необычный возраст!';
alert( message );
Поначалу может быть сложно понять, что происходит. Однако, внимательно приглядевшись, мы замечаем, что это обычная последовательная проверка.
Вопросительный знак проверяет сначала age < 3, если верно – возвращает 'Здравствуй, малыш!', если нет – идет за двоеточие и проверяет age < 18. Если это верно – возвращает 'Привет!', иначе проверка age < 100 и 'Здравствуйте! И наконец, если ничего из этого не верно, то 'Какой необычный возраст!'.
То же самое через if..else:
Пример
'use strict';
var age = prompt('Ваш возраст?', 18);
if (age < 3) {
message = 'Здравствуй, малыш!';
} else if (age < 18) {
message = 'Привет!';
} else if (age < 100) {
message = 'Здравствуйте!';
} else {
message = 'Какой необычный возраст!';
}
alert( message );
3.2 The switch Statement/Инструкция switch
3.2.1 Оператор switch..case..default
Если в вашей программе присутствует большое дерево ветвлений и все ветвления зависят от значения какой-либо одной переменной, то можно вместо ступенчатой последовательности конструкций if...else или else...if воспользоваться инструкцией switch. Рассмотрим простой пример:
Пример
'use strict';
var month = +prompt('Введите месяц в формате 1, 2...12', '1');
switch (month) {
case 1:
alert('Январь');
break;
case 2:
alert('Февраль ');
break;
case 3:
alert('Март');
break;
case 4:
alert('Апрель');
break;
case 5:
alert('Май');
break;
case 6:
alert('Июнь');
break;
case 7:
alert('Июль');
break;
case 8:
alert('Август');
break;
case 9:
alert('Сентябрь');
break;
case 10:
alert('Октябрь');
break;
case 11:
alert('Ноябрь');
break;
case 12:
alert('Декабрь');
break;
}
Различные места в блоке помечены ключевым словом case, за которым следует выражение и символ двоеточия. Ключевое слово case напоминает инструкцию с меткой за исключением того, что оно связывает инструкцию с выражением, а не с именем. Когда выполняется инструкция switch, она вычисляет значение выражения, а затем ищет метку case, соответствующую этому значению (соответствие определяется с помощью оператора идентичности ===). Если метка найдена, выполняется блок кода следующей за меткой case. Если метка case с соответствующим значением не найдена, выполнение начинается с первой инструкции, следующей за специальной меткой default:. Если метка default: отсутствует, блок инструкции switch пропускается целиком.
Обратите внимание на ключевое слово break в конце каждого блока case. Инструкция break, описываемая далее в следующий главе, приводит к передаче управления в конец инструкции switch и продолжению выполнения инструкций, следующих далее. Конструкции case в инструкции switch задают только начальную точку выполняемого программного кода, но не задают никаких конечных точек. В случае отсутствия инструкций break инструкция switch начнет выполнение блока кода с меткой case, соответствующей значению выражения, и продолжит выполнение инструкций до тех пор, пока не дойдет до конца блока. В редких случаях это полезно.
Пример
'use strict';
var month = +prompt('Введите месяц в формате 1, 2...12', '1');
switch (month) {
case 1:
alert('Январь');
break;
case 2:
alert('Февраль ');
break;
case 12:
alert('Декабрь');
break;
default:
alert(month + ' - это не зимний месяц');
}
3.2.2 Группировка case
Несколько значений case можно группировать:
Пример
'use strict';
var month = +prompt('Введите месяц в формате 1, 2...12', '1');
switch (month) {
case 12:
case 1:
case 2:
alert('Зимний месяц');
break;
case 3:
case 4:
case 5:
alert('Весенний месяц');
break;
case 6:
case 7:
case 8:
alert('Летний месяц');
break;
case 9:
case 10:
case 11:
alert('Осенний месяц');
break;
}
3.3 Сравнение switch и if ... else
Когда лучше использовать последовательность if...else (или else...if), а когда — switch? При использовании else...if можно проверять значения разных не связанных друг с другом переменных, причем сравнения могут быть любой степени сложности:
Пример
'use strict';
if (SteamPressure * Factor > 56)
// statement
else if (Voltageln + VoltageOut < 23000)
// statement
else if (day == Thursday)
// statement
else
// statement
В операторе switch все ветвления используют одну и ту же переменную(выражение) единственная возможность проверки в таком ветвлении — сравнение значения переменной с заданной константой. Если хорошо усвоить эти условия, написание конструкций switch становится простым и доступным для понимания, switch рекомендуется использовать там, где это возможно, особенно в случаях, когда дерево ветвлений содержит много ветвей.