Условные операторы

108

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

Если представить, что программа - это дорога, а интерпретатор JavaScript - путешественник, идущий по ней, то условные операторы можно представить как перекрестки, где программный код разветвляется на две или более дорог, и на таких перекрестках интерпретатор должен выбирать, по какой дороге двигаться дальше.

Оператор if/else

Оператор if - это базовый управляющий оператор, позволяющий интерпретатору JavaScript принимать решения или, точнее, выполнять операторы в зависимости от условий. Оператор if имеет две формы. Первая:

if (выражение) 
   оператор

В этой форме сначала вычисляется выражение. Если полученный результат является истинным, то оператор выполняется. Если выражение возвращает ложное значение, то оператор не выполняется. Например:

if (username == null)	// Если переменная username равна null или undefined
   username = "Alex"; // определить ее

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

Вторая форма оператора if вводит конструкцию else, выполняемую в тех случаях, когда выражение возвращает ложное значение. Ее синтаксис:

if (выражение) 
   оператор1
else
   оператор2

Эта форма выполняет оператор1, если выражение возвращает истинное значение, и оператор2, если выражение возвращает ложное значение. Например:

if (n == 1)
   console.log("Получено 1 новое сообщение.");
else
   console.log("Получено " + n + " новых сообщений.");

Оператор else if

Оператор if/else вычисляет значение выражения и выполняет тот или иной фрагмент программного кода, в зависимости от результата. Но что если требуется выполнить один из многих фрагментов? Возможный способ сделать это состоит в применении оператора else if. Формально он не является самостоятельным оператором JavaScript; это лишь распространенный стиль программирования, заключающийся в применении повторяющегося оператора if/else:

if (n == 1) {
    // Выполнить блок 1
}
else if (n == 2) {
    // Выполнить блок 2
}
else if (n == 3) {
    // Выполнить блок 3
}
else {
    // Если ни один из предыдущих операторов else не был выполнен, выполнить блок 4
}

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

Оператор switch

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

Оператор switch предназначен именно для таких ситуаций. За ключевым словом switch следует выражение в скобках и блок кода в фигурных скобках:

switch(выражение) { 
   инструкции
}

Однако полный синтаксис оператора switch более сложен, чем показано здесь. Различные места в блоке помечены ключевым словом 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 внутри функции вместо break можно использовать оператор return. Оба этих оператора служат для завершения работы оператора switch и предотвращения перехода к следующей метке case.)

Ниже приводится более практичный пример использования оператора switch, он преобразует значение в строку способом, зависящим от типа значения:

function convert(x) { 
	switch(typeof x) 
	{ 
		// Преобразовать число в шестнадцатеричное целое
		case 'number':	   
			return x.toString(16);
		// Вернуть строку, заключенную в кавычки
		case 'string':	
			return '"' + x + '"';
		// Любой другой тип преобразуется обычным способом
		default:
			return x.toString();
	}
}

console.log(convert(1067));     // Результат "42b"

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

Оператор switch сначала вычисляет выражение после ключевого слова switch, а затем выражения case в том порядке, в котором они указаны, пока не будет найдено совпадающее значение. Факт совпадения определяется с помощью оператора идентичности ===, а не с помощью оператора равенства ==, поэтому выражения должны совпадать без какого-либо преобразования типов.

Поскольку при каждом выполнении оператора switch вычисляются не все выражения case, следует избегать использования выражений case, имеющих побочные эффекты, такие как вызовы функций и присваивания. Безопаснее всего ограничиваться в выражениях case константными выражениями.

Как объяснялось ранее, если ни одно из выражений case не соответствует выражению switch, оператор switch начинает выполнение оператора с меткой default:. Если метка default: отсутствует, тело оператора switch полностью пропускается. Обратите внимание, что в предыдущих примерах метка default: указана в конце тела оператора switch после всех меток case. Это логичное и обычное место для нее, но на самом деле она может располагаться в любом месте внутри оператора switch.

Тернарный оператор ?:

Тернарный оператор ?: - это единственный тернарный (с тремя операндами) оператор в JavaScript. Этот оператор обычно записывается как ?:, хотя в программах он выглядит по-другому. Он имеет три операнда, первый предшествует символу ?, второй - между ? и :, третий - после :. Используется он следующим образом:

var n = 10;

// Определить четное или нечетное число
var result = (n % 2 == 0) ? "четное" : "нечетное";

console.log(result);     // Результат "четное"

Операнды условного оператора могут быть любого типа. Первый операнд вычисляется и используется как логическое значение. Если первый операнд имеет истинное значение, то вычисляется и возвращается значение выражения во втором операнде. Если первый операнд имеет ложное значение, то вычисляется и возвращается значение выражения в третьем операнде. Вычисляется всегда только какой-то один операнд, второй или третий, и никогда оба.

Тот же результат можно получить с помощью оператора if, но оператор ?: часто оказывается удобным сокращением. Ниже приводится типичный пример, в котором проверяется, определена ли переменная (и имеет истинное значение), и если да, то берется ее значение, а если нет, берется значение по умолчанию:

var message = 'Привет ' + (username ? username : 'друг');

Эта проверка эквивалентна следующей конструкции if, но более компактна:

var message = 'Привет ';

if (username)
{
	message += username;
}
else 
{
	message += 'друг';
}
Пройди тесты
Лучший чат для C# программистов