Перейти к содержимому

Equality: == vs === vs Object.is

В одной фразе: === — строгое сравнение без coercion; == — абстрактное равенство со сложным алгоритмом из спецификации; Object.is — как ===, но корректно обрабатывает NaN и -0. На собесе просят назвать corner cases и объяснить когда применять каждый.

// NaN — единственное значение, не равное самому себе (IEEE 754)
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true — правильная проверка
// Глобальный isNaN() сначала приводит к числу — ловушка!
isNaN('foo'); // true ('foo' → NaN → true) — ложная тревога
Number.isNaN('foo'); // false — нет coercion, только точная проверка
Number.isNaN(NaN); // true
// -0 vs +0: === не различает, Object.is — да
console.log(-0 === +0); // true
console.log(Object.is(-0, +0)); // false
// Почему это важно:
const direction = -0;
console.log(1 / direction); // -Infinity — знак несёт смысл
console.log(String(-0)); // '0' — toString скрывает знак
console.log(JSON.stringify(-0)); // '0' — JSON тоже
// == Abstract Equality: ключевые правила
console.log(null == undefined); // true (особый случай спецификации)
console.log(null == 0); // false (null == только null/undefined)
console.log(null == false); // false
console.log('' == false); // true ('' → 0, false → 0)
console.log('0' == false); // true ('0' → 0, false → 0)
console.log(0 == false); // true (false → 0)
// Практическое правило: == уместен для null-check
const val = null;
val == null; // true — поймает и null, и undefined (но не 0/''/'false')

Итог: Используй === по умолчанию. Object.is — когда нужна точность с NaN и -0. == уместен только как null/undefined-check: val == null.