$ sudo teach IT
РАЗДЕЛ 3 · УРОК 1

Сравнения: == vs ===, операторы сравнения

Программа без решений — это просто калькулятор. Настоящая магия начинается, когда код умеет сравнивать и выбирать. Разберём все операторы сравнения в JavaScript и раскроем одну из самых важных ловушек языка — разницу между == и ===.

⏱ ~20 минут 🎓 Для новичков ⚡ JavaScript

🤔 Зачем программе вообще уметь сравнивать?

Представьте, что вы пишете сайт с авторизацией. Пользователь вводит пароль — и программа должна проверить: совпадает ли введённый пароль с правильным? Без сравнений это невозможно.

Или вы пишете интернет-магазин. Товар стоит 1500 рублей. Есть ли у пользователя на балансе хотя бы столько? Нужно сравнить баланс с ценой. Покупателю 18 лет? Нужно сравнить возраст с числом 18.

Любая реальная программа принимает решения каждую секунду: показать кнопку или нет, пустить пользователя или отказать, выводить скидку или обычную цену. Всё это — сравнения. И результат сравнения всегда один из двух: true (да, правда) или false (нет, ложь).

💡 Запомните: результат любого сравнения — это булево значение: true или false. Именно с этими значениями работают условия if, о которых мы поговорим в следующем уроке.

📏 Операторы сравнения: полный список

Давайте сначала познакомимся со всеми операторами сравнения. Большинство из них вы уже видели на уроках математики — JavaScript просто переносит их в код.

⚖️
== — нестрогое равенство

Проверяет равенство с приведением типов. JavaScript пытается преобразовать значения к одному типу перед сравнением.

🔒
=== — строгое равенство

Проверяет равенство и значения, и типа. Никакого приведения типов — всё честно.

≠
!= — нестрогое неравенство

Противоположность ==. Тоже делает приведение типов перед проверкой.

🚫
!== — строгое неравенство

Противоположность ===. Строго: разные значения или разные типы → true.

< >
< и > — меньше / больше

Классическое математическое сравнение. 5 > 3 → true, 5 < 3 → false.

≤ ≥
<= и >= — меньше/больше или равно

5 >= 5 → true, 5 <= 4 → false. Включают границу.

Посмотрим на примеры простых сравнений в коде:

let age = 20;

console.log(age > 18);    // true  — 20 больше 18
console.log(age < 18);    // false — 20 не меньше 18
console.log(age >= 20);   // true  — 20 больше или равно 20
console.log(age <= 19);   // false — 20 не меньше или равно 19

let price = 1500;
let balance = 1200;
console.log(balance >= price);  // false — денег не хватает

let score = 100;
console.log(score === 100);  // true — точное совпадение
console.log(score !== 50);   // true — 100 не равно 50

Всё это интуитивно понятно. Но теперь мы добираемся до самой интересной (и опасной!) части JavaScript — разницы между == и ===.

🔥 Главная ловушка JS: == vs ===

Это одна из самых знаменитых особенностей JavaScript. Из-за неё новички теряют часы, опытные разработчики допускают баги, и именно её чаще всего спрашивают на собеседованиях.

В JavaScript есть два вида «равно»:

== Нестрогое равенство

JavaScript сначала пытается привести оба значения к одному типу, а потом сравнивает. Это называется type coercion (приведение типов). Результат может вас удивить.

=== Строгое равенство

Сравнивает и значение, и тип. Никаких преобразований. Если типы разные — сразу false. Предсказуемо и безопасно.

Посмотрим на конкретные примеры, которые ломают мозг:

// == с приведением типов — СЮРПРИЗЫ!
console.log("5" == 5);       // true  — строка "5" приводится к числу 5
console.log(0 == false);     // true  — false приводится к числу 0
console.log("" == false);    // true  — "" и false оба становятся 0
console.log(null == undefined); // true — специальное правило JS
console.log(0 == "");        // true  — оба приводятся к 0

// === строгое сравнение — ПРЕДСКАЗУЕМО!
console.log("5" === 5);      // false — строка ≠ число, типы разные
console.log(0 === false);    // false — число ≠ булево значение
console.log("" === false);   // false — строка ≠ булево значение
console.log(null === undefined); // false — разные типы
console.log(0 === "");       // false — число ≠ строка

⚠️ Важно! "5" == 5 возвращает true? Серьёзно?! Да. JavaScript видит: слева строка, справа число. Он думает: «Дай-ка я преобразую строку в число». "5" становится 5. Теперь сравниваем 5 == 5 — true. Вот такая магия, которая чаще всего создаёт баги.

🔬 Как JavaScript приводит типы в ==

Чтобы окончательно разобраться в ==, давайте поймём правила приведения типов. Они не случайные — просто не всегда очевидные.

📌 Правило 1: строка и число

Если сравниваем строку и число — строка преобразуется в число. "42" → 42, "3.14" → 3.14, "" → 0, "abc" → NaN.

"42" == 42   // true  ("42" → 42)
"0" == 0    // true  ("0" → 0)
"" == 0     // true  ("" → 0)
"abc" == 0  // false ("abc" → NaN, и NaN ≠ 0)

📌 Правило 2: булево значение

true преобразуется в 1, false — в 0. Потом сравнивается с другим значением.

true == 1    // true  (true → 1)
false == 0   // true  (false → 0)
true == "1"  // true  (true → 1, "1" → 1)
false == ""  // true  (false → 0, "" → 0)

📌 Правило 3: null и undefined

null == undefined — это true. Особое исключение в JS. Но null и undefined не равны ни чему другому при ==.

null == undefined  // true  — специальное правило
null == 0          // false — null не приводится к 0
null == ""         // false — null не приводится к ""
null == false      // false — и тут тоже нет

🧠 Вывод: правила приведения типов в == нетривиальные и сложные для запоминания. Именно поэтому профессионалы почти всегда используют === — зачем запоминать все эти правила, если можно просто сравнивать честно?

✅ Почему профессионалы используют ===

Теперь, когда вы видели все ужасы ==, давайте ответим на вопрос: зачем тогда == вообще существует? Историческая причина: JavaScript создавался в спешке за 10 дней в 1995 году, и == был попыткой сделать язык «удобным для новичков» — чтобы он прощал ошибки с типами. На практике это привело к обратному.

😱 Реальный пример бага с ==

// Пользователь вводит данные — это ВСЕГДА строка
let userInput = "0";  // пользователь ввёл ноль

// Программист проверяет, ввёл ли пользователь что-нибудь
if (userInput == false) {
  console.log("Пользователь ничего не ввёл!");
}
// Вывод: "Пользователь ничего не ввёл!"
// Но пользователь ввёл "0"! Это БАГ.

// Почему? "0" == false
// "0" → число 0, false → число 0, 0 == 0 → true 😱

✅ Тот же код с ===

let userInput = "0";

if (userInput === false) {
  console.log("Пользователь ничего не ввёл!");
}
// Ничего не выводится — потому что "0" !== false
// Строка не равна булевому значению — правильно!

// Правильная проверка: смотрим длину строки
if (userInput.length === 0) {
  console.log("Поле пустое!");
}

🔑 Золотое правило: всегда используйте === и !==. Ни один профессиональный JavaScript-разработчик не использует == в продакшн-коде без очень веской причины. Большинство линтеров (инструментов проверки кода) автоматически запрещают ==.

🔤 Сравнение строк: лексикографический порядок

Операторы <, >, <=, >= работают не только с числами, но и со строками. Строки сравниваются в лексикографическом порядке — то есть как в словаре, символ за символом.

JavaScript смотрит на код Unicode каждого символа. Буква «a» — это код 97, «b» — 98, «A» — 65. Поэтому заглавные буквы «меньше» строчных!

console.log("apple" < "banana");  // true  — "a" < "b"
console.log("cat" > "car");       // true  — "t" > "r" (на 3-м символе)
console.log("Zoo" < "ant");       // true  — "Z"(90) < "a"(97) — СЮРПРИЗ!
console.log("abc" === "abc");     // true  — строки одинаковые
console.log("abc" === "ABC");     // false — регистр разный!

⚡ На практике: для сравнения строк без учёта регистра используйте str1.toLowerCase() === str2.toLowerCase(). Для сортировки — метод localeCompare().

💻 Практические примеры

Закрепим знания на реальных сценариях:

🔐 Пример 1: Проверка пароля

let correctPassword = "qwerty123";
let userPassword = "qwerty123";

let isCorrect = userPassword === correctPassword;
console.log(isCorrect);  // true — пароль верный!

// Именно === — пароль должен совпадать ТОЧНО
let wrongPassword = "QWERTY123";
console.log(wrongPassword === correctPassword);  // false

🛒 Пример 2: Проверка баланса

let balance = 5000;
let price = 3500;

let canBuy = balance >= price;
console.log(canBuy);  // true — денег достаточно

let afterPurchase = balance - price;
console.log(afterPurchase >= 0);  // true — баланс не уйдёт в минус

📊 Пример 3: Результат сравнений в переменной

let x = 10;
let y = 20;

let isEqual = x === y;         // false
let isNotEqual = x !== y;      // true
let isGreater = x > y;         // false
let isLessOrEqual = x <= y;    // true

console.log(isEqual);          // false
console.log(isNotEqual);       // true
console.log(`${x} меньше или равно ${y}: ${isLessOrEqual}`);
// "10 меньше или равно 20: true"

✅ Итоги урока

  • Сравнения нужны для принятия решений в программе — результат всегда true или false
  • <, >, <=, >= — математические операторы, работают как в школе
  • == — нестрогое равенство, делает приведение типов. "5" == 5 → true (опасно!)
  • === — строгое равенство, проверяет тип и значение. "5" === 5 → false (правильно!)
  • != — нестрогое неравенство с приведением типов
  • !== — строгое неравенство без приведения типов
  • Правило: всегда используйте === и !== — это защищает от неожиданных багов
  • Строки сравниваются лексикографически (как в словаре) — заглавные буквы «меньше» строчных

В следующем уроке мы научим программу принимать решения с помощью if / else — и сравнения из этого урока станут основой для условий. 🚀

Тест: Операторы сравнения

7 вопросов

Проверка возраста

Создайте переменную age = 20 и adultAge = 18. Создайте переменную canVote, которая равна true если age больше или равен adultAge. Создайте переменную isMinor, которая равна true если age меньше adultAge.

Строгое vs нестрогое равенство

Создайте переменную strictResult, которая проверяет строгое равенство строки "10" и числа 10 (через ===). Создайте переменную looseResult, которая проверяет нестрогое равенство тех же значений (через ==).