Чем отличается `==` от `===` в JavaScript?
== сравнивает значения с приведением типов, а === — строгое сравнение, которое требует совпадения и значения, и типа.Суть различия
В JavaScript есть два оператора сравнения на равенство: == (нестрогое, или loose equality) и === (строгое, или strict equality). Главное отличие в том, как они обрабатывают операнды разных типов.
==выполняет приведение типов (type coercion) перед сравнением. Если типы операндов отличаются, JavaScript попытается привести их к общему типу по правилам спецификации.===сравнивает без приведения. Если типы не совпадают — результат сразуfalse, без попыток конвертации.
// Нестрогое сравнение приводит строку к числу
console.log(5 == '5'); // true
// Строгое сравнение видит разные типы и возвращает false
console.log(5 === '5'); // false
Как работает приведение в ==
Алгоритм == (Abstract Equality Comparison) описан в спецификации ECMAScript и содержит несколько правил:
- Если типы совпадают — поведение идентично
===. null == undefined—true, но ни один из них не равен ничему другому.- При сравнении числа и строки строка приводится к числу.
- При сравнении булева значения с чем-либо булев сначала приводится к числу (
true → 1,false → 0). - При сравнении объекта с примитивом объект приводится к примитиву через
ToPrimitive(вызываютсяvalueOf/toString).
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log(0 == false); // true, false → 0
console.log('' == 0); // true, '' → 0
console.log([] == 0); // true, [] → '' → 0
console.log([1] == '1'); // true, [1] → '1'
Именно из-за таких неочевидных правил == часто называют источником багов: результат зависит от цепочки преобразований, которую сложно держать в голове.
Почему рекомендуют ===
В современных стайлгайдах (Airbnb, Google, ESLint правило eqeqeq) по умолчанию требуют ===:
- Поведение предсказуемо: либо типы совпали и значения равны, либо
false. - Не нужно помнить таблицу приведений.
- Легче читать код и находить ошибки на ревью.
- Меньше неожиданных багов на граничных значениях (
0,'',null,NaN, пустые массивы).
// Опасно: пустая строка эквивалентна нулю
if (value == 0) { /* сработает и для '', и для false, и для [] */ }
// Безопасно: только настоящий ноль
if (value === 0) { /* */ }
Когда допустимо использовать ==
Есть один распространённый идиоматический случай — проверка на «отсутствие значения» сразу для null и undefined:
// Сработает и для null, и для undefined
if (value == null) {
// обработка отсутствия значения
}
Это эквивалентно value === null || value === undefined, но короче. В остальных случаях лучше использовать ===.
Отдельный случай: NaN
Ни ==, ни === не работают с NaN: NaN не равен ничему, включая самого себя.
console.log(NaN === NaN); // false
console.log(NaN == NaN); // false
// Правильные способы:
console.log(Number.isNaN(NaN)); // true
console.log(Object.is(NaN, NaN)); // true
Object.is похож на ===, но корректно обрабатывает NaN и различает +0 и -0.
Что хочет услышать интервьюер
Чёткое определение: `==` с приведением типов, `===` без приведения
Понимание алгоритма приведения и ключевых правил (null/undefined, число/строка, булевы)
Знание, что `null == undefined` — true, но `null === undefined` — false
Рекомендацию использовать `===` по умолчанию и обоснование почему
Понимание особенности `NaN` и существования `Object.is`
Пример: Базовое отличие
// Нестрогое сравнение приводит типы
console.log(1 == '1'); // true
console.log(1 == true); // true
console.log(0 == ''); // true
// Строгое сравнение требует совпадения типов
console.log(1 === '1'); // false
console.log(1 === true); // false
console.log(0 === ''); // false
Пример: Идиома проверки на null/undefined
function greet(name) {
// Сработает и для null, и для undefined
if (name == null) {
return 'Привет, гость';
}
return `Привет, ${name}`;
}
console.log(greet(null)); // Привет, гость
console.log(greet(undefined)); // Привет, гость
console.log(greet('Аня')); // Привет, Аня
Пример: Особый случай: NaN
const result = Number('abc'); // NaN
// Оба оператора возвращают false
console.log(result === NaN); // false
console.log(result == NaN); // false
// Корректные проверки
console.log(Number.isNaN(result)); // true
console.log(Object.is(result, NaN)); // true
Типичные ошибки
Утверждение, что `==` сравнивает «по значению», а `===` — «по типу и значению» без объяснения механизма приведения
Забывают про пару `null == undefined` и неправильно описывают её поведение
Считают, что `NaN === NaN` возвращает true
Не знают про правила приведения объектов через `ToPrimitive` (`[] == false` → true)
Категорично заявляют, что `==` использовать нельзя, не зная про идиому `value == null`


