Чем == отличается от === ? Каверзные случаи приведения

Один из самых частых вопросов: «В чём разница между == и === ?»

=== (строгое равенство) сравнивает без приведения типов. == (нестрогое) сначала приводит операнды к общему типу, и эти правила приводят к сюрпризам.

Короткий ответ

=== возвращает true, только если типы и значения совпадают. == при разных типах пытается их «подогнать» друг под друга по сложным правилам. Практический совет, который ценят на собеседовании: используйте всегда ===, кроме одного случая — проверки на «null или undefined» через x == null.

console.log(1 === 1);
console.log(1 === "1");   // разные типы
console.log(1 == "1");    // строка привелась к числу
console.log(0 == false);  // false → 0
console.log("" == 0);     // "" → 0
console.log(null == undefined);
console.log(null === undefined);

Вывод:

true
false
true
true
true
true
false

Каверзный случай: [] == ![]

Этот пример любят на собеседованиях, потому что результат кажется абсурдным. Разберём по шагам.

console.log([] == ![]);

Вывод:

true

Почему: ![] — массив истинный (truthy), значит ![] равно false. Сравнение становится [] == false. Дальше false приводится к числу 0, а [] — к примитиву: пустая строка "", затем к числу 0. Итог: 0 == 0true.

Правила приведения при ==

  • null == undefinedtrue, но ни с чем другим они не равны.
  • Если один операнд число, а другой строка — строка приводится к числу.
  • boolean всегда приводится к числу: true1, false0.
  • Объект приводится к примитиву (через valueOf/toString).

Ещё сюрпризы

console.log("5" - 2);   // оператор - всегда числовой
console.log("5" + 2);   // + со строкой — конкатенация
console.log(true + true);
console.log([1, 2] + [3, 4]);
console.log(null + 1);
console.log(undefined + 1);

Вывод:

3
52
2
1,23,4
1
NaN

Итог

  • === не приводит типы — предсказуемо и безопасно.
  • == приводит операнды по запутанным правилам, отсюда [] == ![]true.
  • Единственное оправданное применение == — проверка x == null (ловит и null, и undefined).
Проверьте себя
1. Что выведет console.log(0 == false)?
Atrue
Bfalse
Cundefined
DОшибку
2. Почему [] == ![] возвращает true?
AМассивы всегда равны друг другу
B![] это false, дальше оба операнда приводятся к числу 0
CЭто баг движка V8
D[] приводится к null
3. Что выведет console.log("5" + 2) и console.log("5" - 2)?
A7 и 3
B52 и 3
C52 и 52
DОшибку
Поддержать проект