StudyCode
&&, ||, !, ??, short-circuit evaluation и как писать защитный код.
Это важно! Логические операторы возвращают один из операндов, а не boolean:
1 || 0 // 1 (первый truthy)
0 || "строка" // "строка" (второй, первый falsy)
0 || null // null (оба falsy — возвращает последний)
"привет" || "дефолт" // "привет"
// Паттерн: значение по умолчанию
const name = user.name || "Гость";
const port = process.env.PORT || 3000;1 && 2 // 2 (оба truthy — последний)
1 && 0 // 0 (первый falsy)
null && "что угодно" // null (null falsy, сразу)
"ok" && "да" // "да" (оба truthy)
// Паттерн: выполнить если условие
isAdmin && showAdminPanel();
user && user.name && greet(user.name);
// Современный вариант:
user?.name && greet(user.name);!true // false
!false // true
!0 // true
!"" // true
!null // true
!"строка" // false
![] // false (массив truthy)
// !! — двойное отрицание, конвертировать в boolean
!!"строка" // true
!!0 // false
!!null // false
// Это то же что Boolean()// Short-circuit evaluation — вычисление "ленивое"
// || останавливается на первом truthy (дальше не вычисляет)
const a = true || expensiveOperation(); // expensiveOperation НЕ вызовется
// && останавливается на первом falsy
const user = null;
const name = user && user.name; // user = null (falsy) → name = null
// user.name НЕ вычисляется (избегаем TypeError)
// Паттерн "охранник" — ранний выход если данных нет:
let userName = null;
let greeting = userName && ("Привет, " + userName);
console.log(greeting); // null (userName был null — дальше не пошло)
userName = "Иван";
greeting = userName && ("Привет, " + userName);
console.log(greeting); // "Привет, Иван" (userName truthy — вычислили правую часть)
// Полезно для безопасного доступа к данным:
let user = null;
let city = user && user.city; // null — не падает с ошибкой
let age = user && user.age; // null&&
AND — останавливается на первом falsy
null && "что угодно"nullне дошли до правого"ok" && "да""да"оба truthy → последнийuser && user.nameбезопаснозащита от nullЕсли левый falsy — вернуть его. Иначе — правый.
||
OR — останавливается на первом truthy
"значение" || "дефолт""значение"первый truthynull || "дефолт""дефолт"null falsy → дальше0 || "дефолт""дефолт"⚠️ 0 тоже falsy!Если левый truthy — вернуть его. Иначе — правый.
Паттерны на практике