Операторы в JavaScript: сравнение, логика, современные
Содержание
О проверке кода. Примеры не запускались — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».
Операторы кажутся мелочью, но именно на них рождаются самые коварные баги JavaScript — приведение типов, NaN, «ложные» значения. Разберём то, что действительно важно.
Сравнение: === против ==
0 == ''; // true ❌ — приведение типов
0 == false; // true ❌
null == undefined; // true ❌
'1' == 1; // true ❌
0 === ''; // false ✅ — разные типы, не равны
0 === false; // false ✅
'1' === 1; // false ✅
== приводит типы перед сравнением — отсюда 0 == '' и '1' == 1, дающие true. Эти правила запутаны и почти всегда не то, что вы имели в виду.
Правило простое: всегда ===. Строгое сравнение проверяет и значение, и тип, без приведения. Единственное исключение, которое иногда оставляют, — x == null для проверки на null или undefined разом, но и то на любителя. Помните: для объектов даже === сравнивает по ссылке, а не по содержимому.
Логические && и || возвращают операнд
Главная неожиданность: в JavaScript && и || возвращают не true/false, а один из операндов.
'Аня' || 'гость'; // 'Аня' — || вернул первый истинный
'' || 'гость'; // 'гость' — '' ложное, взяли второй
0 || 100; // 100
'Аня' && 'привет'; // 'привет' — && вернул последний, все истинны
'' && 'привет'; // '' — && вернул первый ложный
||возвращает первый истинный операнд (или последний, если все ложные) — классический способ дать значение по умолчанию;&&возвращает первый ложный (или последний, если все истинные) — используют для условного доступа.
Оба короткозамкнутые: a && b() не вызовет b(), если a ложное. На этом строят проверки: user && user.name.
?? — нулевое слияние
У || есть ловушка: он считает ложными 0, '', false. Для значений по умолчанию это часто неверно:
const count = 0;
count || 10; // 10 ❌ — 0 ложный, но это валидное значение!
count ?? 10; // 0 ✅ — ?? срабатывает только на null/undefined
?? возвращает правый операнд, только если левый — null или undefined. Ноль, пустая строка и false он пропускает как валидные значения. Это делает ?? правильным выбором для дефолтов, когда 0 или '' — нормальные данные, а не «пусто».
|| — первый истинный
Срабатывает на ЛЮБОМ ложном
0 || 10→ 10 (0 потерян!)'' || 'x'→ ‘x’ (пустая строка потеряна)false || true→ true- Опасно, если 0/’’/false валидны
?? — только null/undefined
Срабатывает только на «нет значения»
0 ?? 10→ 0 ✅'' ?? 'x'→ ’’ ✅null ?? 10→ 10- Правильно для числовых/строковых дефолтов
?. — опциональная цепочка
const user = { name: 'Аня' }; // address нет
user.address.city; // ❌ TypeError: cannot read 'city' of undefined
user?.address?.city; // ✅ undefined — без ошибки
// работает и с методами, и с массивами
user.getEmail?.(); // вызовет, только если метод существует
data?.[0]?.id; // безопасный доступ к элементу массива
?. останавливает обращение и возвращает undefined, если слева null или undefined — вместо падения с TypeError. Убирает громоздкие лесенки user && user.address && user.address.city. Частая связка с ??: user?.address?.city ?? 'не указан' — безопасно достать и подставить дефолт.
Тернарный оператор
const access = age >= 18 ? 'разрешён' : 'запрещён';
// вложенный — читаемо только в меру
const grade = score >= 90 ? 'A' : score >= 70 ? 'B' : 'C';
Тернарный условие ? да : нет — это if/else как выражение, возвращающее значение. Его можно присвоить, вернуть из функции, вставить в шаблонную строку. Удобен для коротких выборов; для сложной логики лучше обычный if, а вложенные тернарники глубже двух уровней уже вредят читаемости.
Полезная мелочь: возведение в степень и присваивания
2 ** 10; // 1024 — оператор степени вместо Math.pow
let x = 5;
x += 3; // 8 — то же, что x = x + 3
x ??= 10; // 8 — присвоить, только если x был null/undefined
let y;
y ??= 10; // 10 — y был undefined
Операторы ** (степень), +=/-=/*= и логические присваивания ??=, ||=, &&= — синтаксический сахар, который делает код короче. x ??= 10 = «присвоить 10, только если x пустой» — удобно для ленивой инициализации.
Смежные темы: примитивы и ссылки — почему === для объектов особый; типы данных — что считается ложным; условия и циклы. Полный список — в уроках JavaScript.