Чем == отличается от === ? Каверзные случаи приведения
Один из самых частых вопросов: «В чём разница между == и === ?»
=== (строгое равенство) сравнивает без приведения типов. == (нестрогое) сначала приводит операнды к общему типу, и эти правила приводят к сюрпризам.
Короткий ответ
=== возвращает 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 == 0 → true.
Правила приведения при ==
null == undefined→true, но ни с чем другим они не равны.- Если один операнд число, а другой строка — строка приводится к числу.
booleanвсегда приводится к числу:true→1,false→0.- Объект приводится к примитиву (через
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).