# Логические операторы В JavaScript поддерживаются операторы `||` (ИЛИ), `&&` (И) и `!` (НЕ). Они называются *"логическими"*, но в JavaScript могут применяться к значениям любого типа и возвращают также значения любого типа. [cut] ## || (ИЛИ) Оператор ИЛИ выглядит как двойной символ вертикальной черты: ```js result = a || b; ``` **Логическое ИЛИ в классическом программировании работает следующим образом: "если *хотя бы один* из аргументов `true`, то возвращает `true`, иначе -- `false`".** Получается следующая таблица результатов: ```js //+ run alert( true || true ); // true alert( false || true ); // true alert( true || false); // true alert( false || false); // false ``` При вычислении ИЛИ в JavaScript можно использовать любые значения. В этом случае они будут интерпретироваться как логические. Например, число `1` будет воспринято как `true`, а `0` -- как `false`: ```js //+ run if ( 1 || 0 ) { // сработает как if( true || false ) alert('верно'); } ``` Обычно оператор ИЛИ используется в `if`, чтобы проверить, выполняется ли хотя бы одно из условий, например: ```js //+ run var hour = 9; *!* if (hour < 10 || hour > 18) { */!* alert('Офис до 10 или после 18 закрыт'); } ``` Можно передать и больше условий: ```js //+ run var hour = 12, isWeekend = true; if (hour < 10 || hour > 18 || isWeekend) { alert('Офис до 10 или после 18 или в выходной закрыт'); } ``` ## Короткий цикл вычислений JavaScript вычисляет несколько ИЛИ слева направо. При этом, чтобы экономить ресурсы, используется так называемый *"короткий цикл вычисления"*. Допустим, вычисляются несколько ИЛИ подряд: `a || b || c || ...`. Если первый аргумент -- `true`, то результат заведомо будет `true` (хотя бы одно из значений -- `true`), и остальные значения игнорируются. Это особенно заметно, когда выражение, переданное в качестве второго аргумента, имеет *сторонний эффект* -- например, присваивает переменную. При запуске примера ниже присвоение `x` не произойдёт: ```js //+ run var x; *!*true*/!* || (x = 1); // просто вычислим ИЛИ, без if alert(x); // undefined, x не присвоен ``` ...А в примере ниже первый аргумент -- `false`, так что ИЛИ попытается вычислить второй, запустив тем самым присваивание: ```js //+ run var x; *!*false*/!* || (x = 1); alert(x); // 1 ``` ## Значение ИЛИ Итак, как мы видим, оператор ИЛИ вычисляет ровно столько значений, сколько необходимо -- до первого `true`. **Оператор ИЛИ возвращает то значение, на котором остановились вычисления.** Примеры: ```js //+ run alert( 1 || 0 ); // 1 alert( true || 'неважно что'); // true alert( null || 1 ); // 1 alert( undefined || 0 ); // 0 ``` Это используют, в частности, чтобы выбрать первое "истинное" значение из списка: ```js //+ run var undef; // переменная не присвоена, т.е. равна undefined var zero = 0; var emptyStr = ""; var msg = "Привет!"; *!* var result = undef || zero || emptyStr || msg || 0; */!* alert(result); // выведет "Привет!" - первое значение, которое является true ``` ## && (И) Оператор И пишется как два амперсанда `&&`: ```js result = a && b; ``` **В классическом программировании И возвращает `true`, если оба аргумента истинны, а иначе -- `false`** ```js //+ run alert( true && true ); // true alert( false && true ); // false alert( true && false); // false alert( false && false); // false ``` Пример: ```js //+ run var hour = 12, minute = 30; if (hour == 12 && minute == 30) { alert('Время 12:30'); } ``` Как и в ИЛИ, допустимы любые значения: ```js //+ run if ( 1 && 0 ) { // вычислится как true && false alert('не сработает, т.к. условие ложно'); } ``` К И применим тот же принцип "короткого цикла вычислений", но немного по-другому, чем к ИЛИ. **Если левый аргумент -- `false`, оператор И возвращает его и заканчивает вычисления, а иначе -- вычисляет и возвращает правый аргумент.** Например: ```js //+ run // Первый аргумент - true, // Поэтому возвращается второй аргумент alert(1 && 0); // 0 alert(1 && 5); // 5 // Первый аргумент - false, // Он и возвращается, а второй аргумент игнорируется alert(null && 5); // null alert(0 && "не важно"); // 0 ``` **Приоритет оператора И `&&` больше, чем ИЛИ `||`, т.е. он выполняется раньше.** Поэтому в следующем коде сначала будет вычислено правое И: `1 && 0 = 0`, а уже потом -- ИЛИ. ```js //+ run alert(5 || 1 && 0); // 5 ``` [warn header="Не используйте `&&` вместо `if`"] Оператор `&&` в простых случаях можно использовать вместо `if`, например: ```js //+ run var x = 1; (x > 0) && alert('Больше'); ``` Действие в правой части `&&` выполнится только в том случае, если до него дойдут вычисления. То есть, если в левой части будет `true`. Получился аналог: ```js //+ run var x = 1; if (x > 0) { alert('Больше'); } ``` Однако, как правило, `if` лучше читается и воспринимается. Он более очевиден, поэтому лучше использовать его. Это, впрочем, относится и к другим неочевидным применениям возможностей языка. [/warn] ## ! (НЕ) Оператор НЕ -- самый простой. Он получает один аргумент. Синтаксис: ```js var result = !value; ``` Действия `!`:
  1. Сначала приводит аргумент к логическому типу `true/false`.
  2. Затем возвращает противоположное значение.
Например: ```js //+ run alert( !true ) // false alert( !0 ) // true ``` **В частности, двойное НЕ используются для преобразования значений к логическому типу:** ```js //+ run alert( !!"строка" ) // true alert( !!null ) // false ```