Перейти к содержимому
Теория · Операторы и приведение типов · урок 5 из 14

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

В обычной речи мы постоянно соединяем условия: «если есть билет и паспорт», «если идёт дождь или снег». В программе для этого есть три логических оператора: && («и»), || («или») и ! («не»).

Каждый из них строит выражение — код, у которого есть значение: a + b, 42, вызов Math.floor(2.5). Со значениями true и false логические операторы работают как в логике. Выражение a && b даёт true, только когда оба значения равны true, а a || b — когда хотя бы одно. Но && и || принимают значения любого типа, и результат у них не обязательно boolean:

JavaScript
console.log(true && false, true || false, !true); // false true false
console.log("Ann" || "guest"); // Ann
console.log("" || "guest"); // guest
console.log(0 && "never"); // 0
console.log(false && true || true); // true

Давайте разберём, что напечаталось:

  1. Первая строка — обычная логика: false true false.
  2. "Ann" || "guest" вернул Ann, само левое значение, а не true.
  3. "" || "guest" вернул guest: пустую строку оператор пропустил.
  4. 0 && "never" вернул 0, и до "never" дело не дошло.
  5. Последняя строка печатает true; почему именно так, разберём ниже.

Оба оператора возвращают одно из двух значений, между которыми стоят.

Что возвращают && и ||

Чтобы выбрать, какое значение вернуть, && и || проверяют левое так, будто оно boolean. Ложными при такой проверке считаются ровно восемь значений:

  • false;
  • 0, -0 и 0n;
  • пустая строка "";
  • null и undefined;
  • NaN.

Минус ноль -0 получается, например, из -1 * 0, а 0n — это ноль типа bigint: на этот тип указывает буква n в конце. Все остальные значения истинные, например "guest" и 42.

Каждый оператор выбирает результат по-своему:

  • || возвращает левое значение, если оно истинное, а иначе правое;
  • && возвращает левое значение, если оно ложное, а иначе правое;
  • ! всегда даёт boolean: !0 даёт true, а !"Ann" — false.

Оператор || удобно представить как бейдж гостя на входе. Гость назвал имя — пишем имя, не назвал — пишем «guest». А && похож на ряд турникетов: проход останавливается у первого закрытого, и результатом становится именно он.

Если открыты все турникеты, результатом становится последний: 5 && 1 даёт 1. На этом картинка заканчивается: настоящий турникет только пропускает или не пропускает, а && возвращает само значение.

Сначала &&, потом ||

В одном выражении && выполняется раньше ||, как * раньше +. Поэтому последняя строка первой программы читается как (false && true) || true:

  1. false && true даёт false;
  2. false || true даёт true.

Скобки делают порядок явным: (a && b) || c. Ставьте их, когда в одном выражении встречаются оба оператора: так его легче читать.

Короткая схема

Если левого значения хватает для ответа, правое даже не вычисляется. Это называют вычислением по короткой схеме. С турникетами то же самое: если первый закрыт, ко второму никто не идёт. После истинного значения || не смотрит направо, и && не смотрит направо после ложного:

JavaScript
function loud() {
    console.log("called");
    return 1;
}

console.log(1 || loud()); // 1
const x = 0 || loud(); // called
console.log(x); // 1

В строке 1 || loud() функция loud не запускается: слева от || уже стоит истинное 1. В строке 0 || loud() слева ложный 0, поэтому loud запускается: печатает called и возвращает 1, и это значение попадает в x.

У && всё зеркально: правую часть он вычисляет только после истинного левого значения. Пройдите программу ниже по шагам и следите, когда над рамкой script появляется рамка loud: только тогда правая часть действительно вычисляется.

ВживуюКороткая схема: когда вызывается loud()шаг 1 из 12 · рамок: 1

Слева истинное 1, поэтому || сразу возвращает его и не вызывает loud().

Рамка loud появляется, только когда вычисляется правая часть

Этот вопрос часто задают на собеседовании: что возвращают && и || и вызовется ли функция справа. Ответ: оператор возвращает одно из двух значений, а правая часть вычисляется, только если левой не хватило для ответа.

Оператор ??

Оператор ?? похож на ||, но правое значение возвращает, только когда левое — null или undefined. Его называют оператором нулевого слияния. На бейдже гостя он напишет «guest», только если графы с именем нет совсем. Значения 0, "" и false — не null и не undefined, поэтому ?? их сохраняет:

JavaScript
console.log(0 || 10, 0 ?? 10); // 10 0
console.log(null ?? 10, undefined ?? 10); // 10 10
console.log(false ?? true); // false

Разберём по строкам:

  1. 0 || 10 даёт 10, потому что 0 ложный, а 0 ?? 10 оставляет 0.
  2. null и undefined оператор ?? заменяет на 10.
  3. false ?? true даёт false: это настоящее значение, а не его отсутствие.

Смешивать ?? с || или && без скобок нельзя: такая строка — синтаксическая ошибка. Со скобками запись работает: (a || b) ?? c.

Частая ошибка

Значение по умолчанию задают через ||, хотя 0 — допустимое значение:

JavaScript
const volume = 0;
const shown = volume || 50; // ✗
console.log(shown); // 50

Громкость 0 ложная, поэтому || заменил её на 50. Когда заменить нужно только отсутствующее значение, пишите volume ?? 50: результат будет 0.

Главное

  • || возвращает левое значение, если оно истинное, иначе правое; && — левое, если оно ложное, иначе правое.
  • Правая часть вычисляется, только если левой не хватило для ответа: это короткая схема.
  • && выполняется раньше ||, а ?? смешивают с ними только через скобки.
  • ?? заменяет только null и undefined, а || — любое ложное значение, даже 0 и "".

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом