Роботландский Университет © А.А.Дуванов

## урок 3: ветвления
дополнительный материал

### функции prompt и confirm

Эти функции, как и функция `alert`, не являются встроенными функциями JavaScript. Это — методы объекта `window`. Однако, до урока 7 на это можно не обращать внимания.

### переключатель

Запись:

    if     (условие1) команда1
    else if(условие2) команда2
    ....
    else if(условиеN) командаN
    else              команда0

гарантирует, что при выполнении i-го условия будет выполнена i-ая команда и только она. Если ни одно из условий не выполняется, будет выполнена `команда0`. Можно использовать и сокращенную форму:

    if     (условие1) команда1
    else if(условие2) команда2
    ....
    else if(условиеN) командаN

Хочется предостеречь от типичной ошибки. Начинающие программисты пишут для переключателя вместо вложенных друг в друга условных команд их последовательную цепочку:

    if(условие1) команда1
    if(условие2) команда2
    ...
    if(условиеN) командаN

Они считают, например, что после выполнения кода:

    x = 1;
    if(x == 1) x += 1;
    if(x == 2) x += 2;
    if(x == 3) x += 3;
    if(x == 4) x += 4;

переменная `x` получит значение 2. На самом деле переменная `x` получит значение 8. Этого не произойдет, если написать:

    x = 1;
    if     (x == 1) x +=1;
    else if(x == 2) x +=2;
    else if(x == 3) x +=3;
    else if(x == 4) x +=4;

Теперь переменная `x` действительно получит значение 2.

### блок

Обычно блок применяют там, где по правилам синтаксиса разрешается использовать только одну команду, а нужно больше (ведь блок — это одна команда!). Новичку кажется, что после выполнения кода:

    x = 1
    if(x != 1) x +=1; x = -x;

значение переменной `x` останется равным 1. На самом деле `x` получит значение -1. Для того чтобы обе команды относились к ветви `true`, их надо “погрузить” в блок:

    x = 1
    if(x != 1) {x +=1; x = -x;}

### условия

Эта одна из самых сложных тем для тех, кто ранее не работал на Си.

Запись

    if(x + y && !z) z = y-x;

для программиста, работающего на Паскале, очень непривычна. Эта команда переписывается в эквивалентном виде так:

    if(x + y != 0 && z==0) z = y-x;

и означает следующее: “Если сумма `x + y` не равна нулю, а `z` равно нулю, то `z` присваивается значение `y-x`”.

Но давайте разбираться по порядку.

Операция “`&&`” — (логическое “и”) является бинарной операцией и приводит к `true`, когда оба операнда имеют значение `true`.

Выражение `a && b` — есть `true` тогда и только тогда, когда и `a` есть `true`, и `b` есть `true`.

В этом смысле запись `x + y != 0 && z==0` становится совершенно понятной, если с учетом приоритета операций, переписать ее в виде: `(x + y != 0) && (z==0)`

Самое сложное место здесь — это соотнесение выражения `x+y` с выражением `x + y != 0`. Ведь когда в качестве условия используется арифметическое выражение, то его значение расценивается как `true`, если оно отлично от нуля, и как `false`, если оно равно нулю.

Иными словами, логическое значение арифметического выражения определяется после его вычисления и сравнения результата с нулем.

Пусть `ав` — любое арифметическое выражение. Тогда запись `if(ав)` совершенно эквивалентна записи `if(ав != 0)`.

Вы можете мысленно заменять `ав` в условиях на `ав != 0` до тех пор, пока не привыкнете.

Число 0, используемое в качестве условия, дает значение `false`, а числа 1, -1, 28, -5.78 и любые другие (кроме нуля) — значение `true`.

Вот пример бесконечного цикла:

    while(1) { ... }

А вот пример цикла, тело которого не выполнится ни разу:

    while(0) { ... }

Выражение `x+y`, используемое в качестве условия, означает совершенно то же, что `x+y != 0`.

Рассмотрим теперь условие `!z`. Оно эквивалентно условию `!(z!=0)`, а последнее — `z==0`.

Запись `!z` означает отрицание логического значения переменной `z`. Если `z` равно нулю (`false`), то `!z` есть `true`. Если `z` не равно нулю (`true`), то `!z` есть `false`.

`0` есть `false`, а `!0` есть `true`
`1` есть `true`, а `!1` есть `false`
`25` есть `true`, а `!25` есть `false`

В качестве условий можно использовать не только арифметические выражения, но и строковые. Логическое значение строки определяется после ее сравнения с пустой строкой (пустая строка ведет себя в этом смысле как ноль).

Пусть `str` — любое строковое выражение. Тогда запись `if(str)` совершенно эквивалентна записи `if(str != "")`.

Вы можете мысленно заменять `str` в условиях на `str != ""` до тех пор, пока не привыкнете.

Вот пример бесконечного цикла:

    while("Дядя"+"Вася") { ... }

А вот пример цикла, тело которого не выполнится ни разу:

    while("") { ... }

### типичная ошибка при записи условия

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

После выполнения кода:

    x = 1;
    if(x = 2) x++;

значение переменной `x` не останется равным единице, а станет равным 3. Ведь в условие записана не операция сравнения (она записывается как “`==`”), а операция присваивания.

### таблица приоритетов операций

Операция | Название | Порядок выполнения
--- | --- | ---
`()` | Группирование. | От внутренних к внешним.
`! - + ++ --` | Логическое отрицание, унарный минус и плюс, увеличение и уменьшение на 1. | Справа налево.
`* / %` | Умножение и деление. | Слева направо.
`+ -` | Сложение и вычитание. | Слева направо.
`< <= >= >` | Операции сравнения. | Слева направо.
`== !=` | Сравнение на равенство и неравенство. | Слева направо.
`&&` | Логическое “и”. | Слева направо.
`||` | Логическое “или”. | Слева направо.

Приоритет понижается сверху вниз.

Например, выражение `+++x` равносильно выражению `+(++x)`, но такие записи лучше не использовать. Когда возникают сомнения в порядке выполнения операций, применяются круглые скобки.

Более полная таблица приоритетов операций приводится в справочном разделе книги.