Возвращаемые значения || и &&

У || и && результат – один из операндов, а не true/false. Этот урок – о том, какой именно операнд возвращается и что из этого следует.

|| возвращает операнд

Результат – одно из исходных значений, а не новое true/false.

or-values.jsjs
const nick = 0 || 'Ира' || 'Гость';// 'Ира' – не true и не falseconsole.log(nick);

В nick – строка 'Ира', а не true. || не создаёт новое булево значение: его результат – одно из исходных значений цепочки. Вычисление идёт слева направо:

  1. Очередной операнд конвертируется в логическое значение. Сам операнд при этом не меняется.
  2. Получилось true – стоп: результат – исходное значение этого операнда. В примере это 'Ира'.
  3. Получилось false – переход к следующему операнду: так пройден 0.
  4. Ложными оказались все – результат – последний операнд цепочки.

Другими словами: цепочка || возвращает первое истинное значение, а если такого нет – последнее.

Взгляните сами – по шагам:

Цепочка ||: стоп на первом истинном
const nick = 0 || 'Ира' || 'Гость';
0ложное значение: переходим к следующему операнду.
const empty = null || 0 || '';
Переменные
Переменных пока нет

Значение по умолчанию

На возврате значений построен частый приём с || – запасное значение: const name = savedName || 'Гость'. Если имя сохранено – берём его, если нет – подставляем «Гостя».

Но у приёма есть ограничение: || подставляет запасное вместо любого ложного значения, включая 0 и пустую строку. А ноль часто – законные данные: количество товара, громкость, счёт игры. 0 || 100 вернёт 100 – ноль заменён запасным, хотя это были данные. Договоримся так: ||-дефолт годится там, где ноль и пустая строка не являются осмысленными данными.

defaults.jsjs
// имя не сохраненоconst savedName = '';// 'Гость' – подставили запасноеconsole.log(savedName || 'Гость');// звук выключен – это данные!const savedVolume = 0;// 50 – ноль ложный, вернулось запасноеconsole.log(savedVolume || 50);
Один приём – два исхода: пустая строка-«не сохранено» заменена по делу, ноль-данные – тоже заменены.

&& возвращает операнд

Тот же обход слева направо, но останавливает его ложное значение.

and-values.jsjs
const bonus = 'ок' && 0 && 'приз';console.log(bonus);  // 0

У && алгоритм зеркальный: та же цепочка слева направо, та же конвертация каждого операнда – но роли true и false меняются местами:

  1. Очередной операнд конвертируется в логическое значение.
  2. Получилось false – стоп: результат – исходное значение этого операнда. В примере это 0.
  3. Получилось true – переход к следующему операнду: 'ок' пройден.
  4. Истинными оказались все – результат – последний операнд цепочки.

Другими словами: цепочка && возвращает первое ложное значение, а если ложных нет – последнее.

И снова по шагам:

Цепочка &&: стоп на первом ложном
const bonus = 'ок' && 0 && 'приз';
'ок'истинное: переходим к следующему операнду.
const all = 1 && 'два' && 'три';
Переменные
Переменных пока нет

Ещё несколько цепочек:

and-cases.jsjs
// null – ложное первым же, дальше не пошлоconsole.log(null && 'бонус');// '' – пустая строка ложнаяconsole.log('' && 'приз');// 'пароль' – оба истинные, вернулся последнийconsole.log('логин' && 'пароль');// 0 – первое ложное оказалось последнимconsole.log(7 && 'семь' && 0);

Короткое замыкание

Всё правее точки остановки не вычисляется вовсе.

В обоих степперах операнды правее точки остановки не вычислялись – это называют коротким замыканием. Пропускается не только вычисление значения: вызов функции в правой части тоже не произойдёт:

short-circuit.jsjs
const isReady = false;// тишина: до правой части не дошлоisReady && console.log('поехали');// тишина: ответ определён левым операндомtrue || console.log('не дойдёт');// 'дошло' – без правой части ответа нетfalse || console.log('дошло');
Правая часть – не «вторая половина формулы», а код, который может не выполниться вовсе.

Раз правая часть может не выполниться, её используют как действие с условием: isReady && console.log('поехали') напечатает строку, только если слева истина. Читать такое вы будете часто; писать – умеренно: для действий обычно пишут if.

// теперь вы знаете

  1. || и && возвращают исходный операнд: || – первый истинный, && – первый ложный; не нашлось – последний
  2. Оба вычисляют операнды слева направо и останавливаются, как только ответ определён
  3. Короткое замыкание: правая часть может не вычисляться вовсе
  4. ||-дефолт подставляет запасное вместо 0 и пустой строки – годится не для всяких данных

Проверьте себя

Что вернёт undefined || 0 || 'да'?

Что напечатает console.log(1 && 0 && 'три')?

Что возвращают эти два выражения?

'Ира' || 'Гость'
Boolean('Ира' || 'Гость')

Отметьте выражения, результат которых – строка 'Гость'.

Выбери все верные варианты

Громкость сохранена как 0. Что выведет console.log(0 || 30)?

переключают уроки · не работают при фокусе в полях ввода