Послание № 5
Условные инструкции
Условные инструкции позволяют выполнять или пропускать любой блок кода в зависимости от условия. Эти инструкции являются точками принятия решений в программе, и иногда их также называют инструкциями «ветвления».
Если представить, что программа – это дорога, а интерпретатор JavaScript – путешественник, идущий по ней, то условные инструкции можно представить, как перекрестки, где программный код разветвляется на две или более дорог, и на таких перекрестках интерпретатор должен выбирать, по какой дороге двигаться дальше.
Инструкция if (если)
Инструкция if – это базовая управляющая инструкция, позволяющая интерпретатору JavaScript принимать решения или, точнее, выполнять инструкции в зависимости от условий.
Инструкция имеет две формы:
1. if (выражение) инструкция; — В этой форме сначала вычисляется выражение. Если полученный результат является истинным, то инструкция выполняется. Если выражение возвращает ложное значение, то инструкция не выполняется, и просто пропускается.
Например:
if (age >= 100) alert(“Вы долгожитель”);
// Если переменная age больше или равна 100 то мы выводим alert()
// Если переменная age равна другому значению, то alert() не выводится и просто пропускается
2. if (выражение) инструкция1; else инструкция2; — Вторая форма инструкции if вводит конструкцию else, выполняемую в тех случаях, когда выражение возвращает ложное значение.
Например:
if (age >= 18) alert(“Вы совершеннолетний человек”);
else alert(“Вам еще не исполнилось 18 лет”);
//Если переменная age меньше 18, то выводится второй alert()
При наличии вложенных инструкций if с блоками else требуется некоторая осторожность – необходимо гарантировать, что else относится к соответствующей ей инструкции if. Согласно правилам JavaScript (и большинства других языков программирования), конструкция else является частью ближайшей к ней инструкции if.
Важно!
· Скобки вокруг условного выражения являются обязательной частью синтаксиса инструкции if.
If (условное выражение приводящее значение к логическому типу) инструкция;
· Синтаксис языка JavaScript позволяет вставить только одну инструкцию после инструкции if и выражения в круглых скобках или else, однако одиночную инструкцию всегда можно заменить блоком инструкций. Поэтому инструкция if может выглядеть так:
if (address) {
message = "Спасибо! Скоро мы вышлем Вам посылку. ";
}
else {
address = "";
message = "Пожалуйста, укажите почтовый адрес.";
}
Инструкция else if
Инструкция if вычисляет значение выражения и выполняет тот или иной фрагмент программного кода в зависимости от результата. Но что если требуется выполнить один из многих фрагментов? Возможный способ сделать это состоит в применении инструкции else if. Формально она не является самостоятельной инструкцией JavaScript; это лишь распространенный стиль программирования, заключающийся в применении повторяющихся инструкций if/else:
if (n == 1) {// Выполнить блок кода 1}
else if (n == 2) {// Выполнить блок кода 2}
else if (n == 3) {// Выполнить блок кода 3}
else if (n == 4) {// Выполнить блок кода 4}
else {// Если ни одна из предыдущих инструкций else не была выполнена, выполнить блок 5}
В этом примере нет ничего особенного. Это просто последовательность инструкций if, где каждая инструкция if является частью конструкции else предыдущей инструкции.
Стиль else if предпочтительнее и понятнее записи в синтаксически эквивалентной форме, полностью показывающей вложенность инструкций:
Условный оператор (?:)
Условный оператор – это единственный тернарный (с тремя операндами) оператор, и иногда он так и называется – «тернарный оператор».
Этот оператор обычно записывается как …?...: …;
Он имеет три операнда, первый перед символом?, второй между? и:, третий после:.
username? console.log("hello " + username): console.log("hello Anonymous");
Операнды условного оператора могут быть любого типа.
Первый операнд вычисляется и используется как логическое значение. Если первый операнд имеет истинное значение, то вычисляется и возвращается значение выражения во втором операнде. Если первый операнд имеет ложное значение, то вычисляется и возвращается значение выражения в третьем операнде.
Вычисляется всегда только какой-то один операнд, второй или третий, и никогда оба.
Тот же результат можно получить с помощью инструкции if, но оператор?: часто оказывается удобным сокращением.
Вот пример, в котором проверяется, определена ли переменная, и если да, то берется ее значение, а если нет, берется значение по умолчанию:
greeting = "hello " + (username? username: "there");
Эта проверка эквивалентна следующей конструкции if, но более компактна:
greeting = "hello ";
if (username) greeting += username;
else greeting += "there";
Инструкция switch
Инструкция if создает ветвление в потоке выполнения программы, а многопозиционное ветвление можно реализовать посредством нескольких инструкций else if. Однако это не всегда наилучшее решение, особенно если все ветви зависят от значения одного выражения. В этом случае расточительно повторно вычислять значение одного и того же выражения в нескольких инструкциях if.
Инструкция switch предназначена именно для таких ситуаций.
За ключевым словом switch следует выражение в скобках и блок кода в фигурных скобках:
switch(выражение) { инструкции }
Однако полный синтаксис инструкции switch более сложен, чем показано здесь.
Различные места в блоке помечены ключевым словом case, за которым следует выражение и символ двоеточия. Ключевое слово case напоминает инструкцию с меткой за исключением того, что оно связывает инструкцию с выражением, а не с именем.
Когда выполняется инструкция switch, она вычисляет значение выражения, а затем ищет метку case, соответствующую этому значению (соответствие определяется с помощью оператора идентичности ===).
Если метка найдена, выполняется блок кода, начиная с первой инструкции, следующей за меткой case. Если метка case с соответствующим значением не найдена, выполнение начинается с первой инструкции, следующей за специальной меткой default:. Если метка default: отсутствует, блок инструкции switch пропускается целиком.
Работу инструкции switch сложно объяснить на словах, гораздо понятнее выглядит объяснение на примере. Следующая инструкция switch эквивалентна повторяющимся инструкциям if/else, показанным в предыдущем разделе:
switch(n) {
case 1: // Выполняется, если n === 1 // Выполнить блок 1. break; // Здесь остановиться
case 2: // Выполняется, если n === 2 // Выполнить блок 2. break; // Здесь остановиться
case 3: // Выполняется, если n === 3 // Выполнить блок 3. break; // Здесь остановиться
default: // Если все остальное не подходит... // Выполнить блок 4. break; // Здесь остановиться
}
Обратите внимание на ключевое слово break в конце каждого блока case.
Инструкция break, приводит к передаче управления в конец инструкции switch и продолжению выполнения инструкций, следующих далее.
Конструкции case в инструкции switch задают только начальную точку выполняемого программного кода, но не задают никаких конечных точек. В случае отсутствия инструкций break инструкция switch начнет выполнение блока кода с меткой case, соответствующей значению выражения, и продолжит выполнение инструкций до тех пор, пока не дойдет до конца блока. В редких случаях это полезно для написания программного кода, который переходит от одной метки case к следующей, но в 99% случаев следует аккуратно завершать каждый блок case инструкцией break.
Инструкция switch сначала вычисляет выражение после ключевого слова switch, а затем выражения case в том порядке, в котором они указаны, пока не будет найдено совпадающее значение.
Логические выражения (и, или, не)
Логические операторы && (и), || (или),! (не) используются для выполнения операций булевой алгебры и часто применяются в сочетании с операторами отношений для объединения двух выражений отношений в одно более сложное выражение.
Логическое И (&&)
Свою работу оператор начинает с вычисления первого операнда – выражения слева.
Если выражение слева возвращает ложное значение, значением всего выражения также должно быть ложное значение, поэтому оператор && просто возвращает значение слева и не вычисляет выражение справа. В противном случае, если значение слева является истинным, тогда результат всего выражения определяется значением справа.
Если значение справа является истинным, значением всего выражения также должно быть истинное значение, а если значение справа является ложным, значением всего выражения должно быть ложное значение. Поэтому, когда значение слева является истинным, оператор && вычисляет и возвращает значение справа:
let i = NaN;
i = i && 5; // в переменную возвращается значение NaN, потому что NaN в логическом типе это — false
Так же оператор && часто используется для объединения двух выражений отношений:
x == 0 && y == 0 // true тогда и только тогда, когда x и y равны 0
Когда в операции участвуют логические операнды, оператор && выполняет операцию «логическое И» над двумя значениями: он возвращает true тогда и только тогда, когда оба операнда имеют значение true. Если один или оба операнда имеют значение false, оператор возвращает false.
Операторы отношений имеют более высокий приоритет, чем оператор && (и ||), поэтому такие выражения можно записывать без использования скобок.
Важно понимать, что оператор && может не вычислять выражение правого операнда.
Иногда можно встретить программный код, в котором поведение оператора && используется специально для выполнения инструкций по условию. Например, следующие две строки дают одинаковый результат:
if (a == b) stop(); // Функция stop() вызывается, только если a == b
(a == b) && stop(); // То же самое
В целом следует с осторожностью использовать выражения с побочными эффектами (присваивания, инкременты, декременты или вызовы функций) справа от оператора &&, потому что эти побочные эффекты будут проявляться в зависимости от значения слева.
Несмотря на довольно запутанный алгоритм работы этого оператора, проще всего и абсолютно безопасно рассматривать его как оператор булевой алгебры, который манипулирует истинными и ложными значениями.
Логическое ИЛИ (||)
Оператор || выполняет операцию «логическое ИЛИ» над двумя операндами. Если один или оба операнда имеют истинное значение, он возвращает истинное значение. Если оба операнда имеют ложные значения, он возвращает ложное значение.
Хотя оператор || чаще всего применяется просто как оператор «логическое ИЛИ», он, как и оператор &&, ведет себя более сложным образом.
Его работа начинается с вычисления первого операнда, выражения слева. Если значение этого операнда является истинным, возвращается истинное значение. В противном случае оператор вычисляет второй операнд, выражение справа, и возвращает значение этого выражения.
Как и при использовании оператора &&, следует избегать правых операндов, имеющих побочные эффекты, если только вы умышленно не хотите воспользоваться тем обстоятельством, что выражение справа может не вычисляться.
Характерное использование этого оператора заключается в том, что он выбирает первое истинное значение из предложенного множества альтернатив:
// Если переменная max_width определена, используется ее значение. В противном случае значение извлекается из объекта preferences. Если объект (или его свойство max_with) не определен, используется значение константы, жестко определенной в тексте программы.
var max = max_width || preferences.max_width || 500;
Логическое НЕ (!)
Оператор! является унарным оператором, помещаемым перед одним операндом.
Он используется для инверсии логического значения своего операнда.
Например, если переменная x имеет значение true, то выражение !x возвращает значение false, и наоборот.
В отличие от операторов && и ||, оператор! преобразует свой операнд в логическое значение перед тем, как инвертировать его. Это означает, что оператор! всегда возвращает true или false, и это означает, что всегда можно преобразовать любое значение в его логический эквивалент, дважды применив этот оператор:!!.
Будучи унарным, оператор! имеет высокий приоритет и тесно связан с операндом, и если вам потребуется инвертировать значение выражения, такого как p && q, необходимо будет использовать круглые скобки:!(p && q).