en.javascript.info/01-js/02-first-steps/13-logical-ops/article.md
Ilya Kantor f301cb744d init
2014-10-26 22:10:13 +03:00

7.9 KiB
Raw Blame History

Логические операторы

В JavaScript поддерживаются операторы || (ИЛИ), && (И) и ! (НЕ).

Они называются "логическими", но в JavaScript могут применяться к значениям любого типа и возвращают также значения любого типа. [cut]

|| (ИЛИ)

Оператор ИЛИ выглядит как двойной символ вертикальной черты:

result = a || b;

Логическое ИЛИ в классическом программировании работает следующим образом: "если хотя бы один из аргументов true, то возвращает true, иначе -- false".

Получается следующая таблица результатов:

//+ run
alert( true  || true ); // true
alert( false || true ); // true
alert( true  || false); // true
alert( false || false); // false

При вычислении ИЛИ в JavaScript можно использовать любые значения. В этом случае они будут интерпретироваться как логические.

Например, число 1 будет воспринято как true, а 0 -- как false:

//+ run
if ( 1 || 0 ) { // сработает как if( true || false )
  alert('верно');
}

Обычно оператор ИЛИ используется в if, чтобы проверить, выполняется ли хотя бы одно из условий, например:

//+ run
var hour = 9;

*!*
if (hour < 10 || hour > 18) { 
*/!*
  alert('Офис до 10 или после 18 закрыт');
}

Можно передать и больше условий:

//+ run
var hour = 12, isWeekend = true;

if (hour < 10 || hour > 18 || isWeekend) {
  alert('Офис до 10 или после 18 или в выходной закрыт');
}

Короткий цикл вычислений

JavaScript вычисляет несколько ИЛИ слева направо. При этом, чтобы экономить ресурсы, используется так называемый "короткий цикл вычисления".

Допустим, вычисляются несколько ИЛИ подряд: a || b || c || .... Если первый аргумент -- true, то результат заведомо будет true (хотя бы одно из значений -- true), и остальные значения игнорируются.

Это особенно заметно, когда выражение, переданное в качестве второго аргумента, имеет сторонний эффект -- например, присваивает переменную.

При запуске примера ниже присвоение x не произойдёт:

//+ run
var x;

*!*true*/!* || (x = 1);  // просто вычислим ИЛИ, без if

alert(x); // undefined, x не присвоен

...А в примере ниже первый аргумент -- false, так что ИЛИ попытается вычислить второй, запустив тем самым присваивание:

//+ run
var x;

*!*false*/!* || (x = 1);
alert(x); // 1

Значение ИЛИ

Итак, как мы видим, оператор ИЛИ вычисляет ровно столько значений, сколько необходимо -- до первого true.

Оператор ИЛИ возвращает то значение, на котором остановились вычисления.

Примеры:

//+ run
alert( 1 || 0 ); // 1 
alert( true || 'неважно что'); // true

alert( null || 1 ); // 1
alert( undefined || 0 ); // 0

Это используют, в частности, чтобы выбрать первое "истинное" значение из списка:

//+ run
var undef; // переменная не присвоена, т.е. равна undefined
var zero = 0; 
var emptyStr = "";
var msg = "Привет!";

*!*
var result = undef || zero || emptyStr || msg || 0;
*/!*

alert(result); // выведет "Привет!" - первое значение, которое является true

&& (И)

Оператор И пишется как два амперсанда &&:

result = a && b;

В классическом программировании И возвращает true, если оба аргумента истинны, а иначе -- false

//+ run
alert( true  && true ); // true
alert( false && true ); // false
alert( true  && false); // false
alert( false && false); // false

Пример:

//+ run
var hour = 12, minute = 30;

if (hour == 12 && minute == 30) {
  alert('Время 12:30');
}

Как и в ИЛИ, допустимы любые значения:

//+ run
if ( 1 && 0 ) { // вычислится как true && false
  alert('не сработает, т.к. условие ложно');
}

К И применим тот же принцип "короткого цикла вычислений", но немного по-другому, чем к ИЛИ.

Если левый аргумент -- false, оператор И возвращает его и заканчивает вычисления, а иначе -- вычисляет и возвращает правый аргумент.

Например:

//+ run
// Первый аргумент - true, 
// Поэтому возвращается второй аргумент
alert(1 && 0);  // 0
alert(1 && 5);  // 5

// Первый аргумент - false,
// Он и возвращается, а второй аргумент игнорируется
alert(null && 5);  // null
alert(0 && "не важно"); // 0

Приоритет оператора И && больше, чем ИЛИ ||, т.е. он выполняется раньше.

Поэтому в следующем коде сначала будет вычислено правое И: 1 && 0 = 0, а уже потом -- ИЛИ.

//+ run
alert(5 || 1 && 0); // 5

[warn header="Не используйте && вместо if"]

Оператор && в простых случаях можно использовать вместо if, например:

//+ run
var x = 1;

(x > 0) && alert('Больше');

Действие в правой части && выполнится только в том случае, если до него дойдут вычисления. То есть, если в левой части будет true.

Получился аналог:

//+ run
var x = 1;

if (x > 0) {
  alert('Больше');
}

Однако, как правило, if лучше читается и воспринимается. Он более очевиден, поэтому лучше использовать его. Это, впрочем, относится и к другим неочевидным применениям возможностей языка. [/warn]

! (НЕ)

Оператор НЕ -- самый простой. Он получает один аргумент. Синтаксис:

var result = !value;

Действия !:

  1. Сначала приводит аргумент к логическому типу `true/false`.
  2. Затем возвращает противоположное значение.

Например:

//+ run
alert( !true ) // false
alert( !0 )  // true

В частности, двойное НЕ используются для преобразования значений к логическому типу:

//+ run
alert( !!"строка" )  // true
alert( !!null ) // false