В JavaScript часто возникает ситуация, когда нужно принять решение на основе нескольких условий или подставить значение по умолчанию, если данные отсутствуют. Например, при выводе имени пользователя в интерфейсе:
- Если имя указано — показываем его.
- Если имя не указано — показываем "Гость".
Для таких сценариев разработчики часто используют логические операторы &&, || и ??. Они позволяют компактно записывать условия, управлять потоком выполнения и обрабатывать значения по умолчанию. В этом уроке мы разберём, как работает ленивая оценка в && и ||, зачем нужен оператор ?? и как их правильно применять.
Что вы узнаете в рамках статьи
- Что такое ленивая оценка и как она работает.
- Как использовать
||и&&для проверки условий и присвоения значений. - Чем отличается
??от||. - В каких случаях можно (и не стоит) применять эти операторы.
Ключевые термины
- Ленивая оценка (short-circuit evaluation) — механизм, при котором вычисления останавливаются, как только результат выражения становится очевиден.
- Оператор
||(логическое ИЛИ) — возвращает первый истинный операнд или последний, если все ложные. - Оператор
&&(логическое И) — возвращает первый ложный операнд или последний, если все истинные. - Оператор
??(Nullish coalescing) — возвращает первый операнд, который не равенnullиundefined.
Ленивая оценка: суть и пример
Ленивая оценка (short-circuit evaluation) — это приём, при котором JavaScript прекращает проверку условий, как только результат становится очевидным.
Представьте, что вы идёте по чек-листу:
- "Сегодня хорошая погода?" — Нет → остальные пункты про пикник можно не проверять.
- "Есть ли у нас еда?" — Неважно, мы уже решили, что пикник отменяется.
JavaScript действует точно так же:
- В
||(ИЛИ): если хотя бы одно условиеtrue, всё выражение будетtrue→ дальше проверять смысла нет. - В
&&(И): если хотя бы одно условиеfalse, всё выражение будетfalse→ дальше проверять смысла нет.
Пример с ||:
const a = 0;
if (a > -1 || b < 4) {
console.log("Первое условие выполнилось");
}
- Шаг 1: Проверяем
a > -1→ этоtrue(0 больше -1). - Шаг 2: Так как
||работает по принципу "нашёл истину — хватит", второе условие (b < 4) даже не вычисляется. - Результат: ошибки нет, хотя
bне определена.
Пример с &&:
const x = -12;
if (x > -1 && b < 4) {
console.log("Сообщение не выведется");
} else {
console.log("А это выведется");
}
- Шаг 1:
x > -1→false. - Шаг 2: Для
&&это уже достаточно, чтобы вернутьfalseдля всего выражения. - Второе условие (
b < 4) не проверяется — ошибки нет.
Преимущество: экономия времени и ресурсов.
Опасность: можно забыть, что вторая часть не будет выполняться, и поместить туда важный код.
Оператор || — логическое ИЛИ
Оператор || (логическое ИЛИ) проверяет операнды слева направо и возвращает первый, который приводится к true (truthy). Если таких нет — возвращает последний.
Важно: результатом работы
||может быть не толькоtrueилиfalse, а любое значение операнда.
Как это работает
операнд1 || операнд2
- Если операнд1 truthy (истинное значение) → вернуть операнд1, и дальнейшие проверки не выполняются (ленивая оценка).
- Если операнд1 falsy (ложное значение) → вернуть операнд2.
Truthy — любое значение, которое в логическом контексте считается
true.
Falsy — любое значение, которое в логическом контексте считаетсяfalse.
Пример 1: Истинный первый операнд
const a = 5;
const b = 10;
const result = a || b;
console.log(result); // 5
a→ truthy (любое ненулевое число — истина)- Возвращаем
a,bдаже не проверяется.
Пример 2: Ложный первый операнд
const a = 0;
const b = 10;
const result = a || b;
console.log(result); // 10
a→ falsy (0считается ложью)- Возвращаем второй операнд
b.
Пример 3: Несколько операндов
|| можно цепочкой использовать для поиска первого truthy-значения:
const result = 0 || '' || null || 'Hello' || 'World';
console.log(result); // 'Hello'
0→ falsy''→ falsynull→ falsy'Hello'→ truthy → возвращаем его.
Применение для значений по умолчанию
Один из самых популярных сценариев — подстановка значения, если переменная пуста:
const userInput = ''; // пользователь ничего не ввёл
const username = userInput || 'Anonymous';
console.log(username); // 'Anonymous'
userInputпустая строка → falsy- Берём
'Anonymous'как запасное значение.
Недостаток ||
|| считает falsy не только null и undefined, но и:
0''(пустая строка)falseNaN
Иногда это мешает. Например:
const pageNumber = 0;
const currentPage = pageNumber || 1;
console.log(currentPage); // 1, хотя мы хотели 0
Здесь || воспринял 0 как ложь и вернул 1, что не всегда правильно.
Решение — использовать оператор
??(Nullish Coalescing), который реагирует только наnullиundefined:
const currentPage = pageNumber ?? 1;
console.log(currentPage); // 0
Оператор && — логическое И
Оператор && (логическое И) проверяет операнды слева направо и возвращает первый, который приводится к false (falsy). Если все операнды истинные — возвращает последний.
В отличие от
||, который ищет первый истинный элемент,&&ищет первый ложный.
Как это работает
операнд1 && операнд2
- Если операнд1 falsy → вернуть операнд1, и дальнейшие проверки не выполняются (ленивая оценка).
- Если операнд1 truthy → перейти к проверке операнд2 и вернуть его результат.
Truthy и Falsy значения те же, что и у
||.
Пример 1: Первый операнд ложный
const c = 0;
const d = 20;
const result = c && d;
console.log(result); // 0
c→ falsy (0— ложь)- Возвращаем
c, даже не проверяяd.
Пример 2: Первый операнд истинный
const c = 5;
const d = 20;
const result = c && d;
console.log(result); // 20
c→ truthy- Проверяем второй операнд и возвращаем его.
Пример 3: Несколько операндов
const result = 5 && 'Hello' && 42 && true;
console.log(result); // true
Все операнды truthy → возвращаем последний (true).
const result2 = 5 && 0 && 'Hello';
console.log(result2); // 0
Проверка останавливается на первом falsy (0).
Условное выполнение с &&
Часто используется для выполнения кода только при выполнении условия, чтобы не писать if:
discount && (price = price - price / 100 * discount);
- Если
discounttruthy → выполняется правая часть и пересчитывается цена. - Если
discountfalsy → правая часть не выполняется,priceостаётся без изменений.
Оператор ?? — объединение с nullish-значениями
Оператор ?? (Nullish Coalescing) возвращает первый операнд, который не является null или undefined. Если первый операнд — null или undefined, возвращается второй.
Главная идея — дать значение по умолчанию, но при этом считать
0, пустую строку иfalseвалидными значениями, а не ложными.
Как это работает
операнд1 ?? операнд2
- Если операнд1 не
nullи неundefined→ вернуть операнд1. - Если операнд1
nullилиundefined→ вернуть операнд2.
Пример 1: Значение null
const foo = null;
const bar = 'default';
const result = foo ?? bar;
console.log(result); // 'default'
foo — это null → возвращаем bar.
Пример 2: Значение undefined
let value;
const result = value ?? 100;
console.log(result); // 100
value не инициализирована → undefined → берём 100.
Пример 3: В отличие от ||
const count = 0;
console.log(count || 10); // 10 — потому что 0 считается falsy в `||`
console.log(count ?? 10); // 0 — потому что 0 не null/undefined
Вывод:
??не заменит0или пустую строку, если они осмысленны в вашем коде.
Пример 4: Пустая строка как допустимое значение
const username = '';
const result = username ?? 'Guest';
console.log(result); // '' — пустая строка, а не 'Guest'
Если бы мы использовали ||, получили бы 'Guest', что могло бы быть ошибкой в логике.
Пример 5: С цепочкой вызовов (optional chaining)
?? часто используют вместе с ?. для безопасного доступа к свойствам:
const user = { profile: { name: '' } };
const name = user?.profile?.name ?? 'No name';
console.log(name); // '' — пустая строка, не 'No name'
Это полезно, когда пустое значение — это валидная информация.
Важные моменты
Приоритет у ?? ниже, чем у большинства операторов, поэтому иногда нужны скобки:
const x = 1 + (null ?? 2); // 3
Нельзя напрямую комбинировать ?? с || или && без скобок — это вызовет ошибку:
// Ошибка SyntaxError
let x = null ?? false || true;
// Нужно явно указать порядок
let y = (null ?? false) || true;
Наиболее частые ошибки
-
Путаница между
||и??0 || 'default' // 'default' 0 ?? 'default' // 0 -
Использование
&&без понимания возврата значения — иногда забывают, что&&возвращает сам операнд, а не простоtrue/false. -
Вложенные тернарники и логические операторы без скобок — ухудшают читаемость.
Наиболее частые вопросы
В: Можно ли использовать ?? с && и || вместе?
О: Да, но стоит быть осторожным и использовать скобки для явного порядка вычислений.
В: Почему || иногда даёт неожиданный результат?
О: Потому что он считает 0, '' и false ложными значениями, даже если они валидны.
В: Что быстрее — if или &&/||?
О: Скорость практически одинакова, но if часто читается проще.
Итоги
Сегодня вы узнали:
- Как работает ленивая оценка и почему она ускоряет выполнение кода.
- Как
||помогает задавать значения по умолчанию, а&&— выполнять код только при истинности условия. - Чем
??отличается от||и когда его лучше использовать.
Эти операторы делают код компактнее, но всегда думайте о читаемости. Если условие сложное — используйте
if.