Объясните поведение следующих выражений в JavaScript и причины: 0 == '0', 0 === '0', [] == ![], null == undefined — почему такие сравнения вызывают путаницу и какие практики сравнения рекомендуется использовать

1 Июн в 14:40
10 +1
0
Ответы
1
Результаты и почему (сжатo, с ключевыми шагами преобразований JS):
1) 0==′0′ \;0 == '0'\;0==0 — true.
Алгоритм: при абстрактном равенстве, если типы разные и один — строка, строка приводится к числу: ′0′→0'0' \to 000. Сравниваем 0==00 == 00==0 → true.
2) 0===′0′ \;0 === '0'\;0===0 — false.
Строгое равенство (=ˉ=\====ˉ=) не делает приведения типов: разные типы (Number vs String) → сразу false.
3) []==![] \;[] == ![]\;[]==![] — true (удивляет). Разбор:
- Сначала вычисляется ![]![]![]. Пустой массив — truthy, значит ![]→false![] \to false![]false.
- Получаем []==false[] == false[]==false.
- При сравнении Boolean с другим типом булевое значение приводится к числу: false→0false \to 0false0. Значит []==0[] == 0[]==0.
- Объект (массив) приводится к примитиву: пустой массив даёт строку ′′''′′ (пустая строка). Затем строка приводится к числу: ′′→0'' \to 0′′0.
- Итого 0==00 == 00==0 → true.
4) null==undefined \;null == undefined\;null==undefined — true.
Специальное правило в спецификации: при абстрактном равенстве null и undefined считаются равными друг другу и только друг другу. Другие сравнения с null (например null==0null == 0null==0) дают false.
Почему это вводит в заблуждение:
- Операция =ˉ\===ˉ делает много неочевидных неявных приводений (ToPrimitive, ToNumber, ToString, ToBoolean) по разным правилам в зависимости от типов; есть специальные исключения (null/undefined). Это даёт множество сюрпризов (пример с []==![][] == ![][]==![], null==0\;null == 0null==0 и т.д.).
Рекомендуемые практики:
- Используйте строгое сравнение =ˉ=\====ˉ= и ⁣==\!==== по умолчанию.
- Для явных преобразований типов используйте Number(), String(), Boolean() перед сравнением, если нужно (не полагайтесь на неявное приведение).
- Если нужно проверить «null или undefined», можно явно писать (x===null ∣∣ x===undefined)(x === null \,||\, x === undefined)(x===null∣∣x===undefined) или намеренно использовать (x==null)(x == null)(x==null) как идиому, но документируйте это правило и включите правило lint (eslint rule eqeqeq) с нужными исключениями.
- Для особых случаев сравнения (NaN, -0/+0) используйте Object.is: Object.is(NaN,NaN)\text{Object.is}(NaN, NaN)Object.is(NaN,NaN) → true, Object.is(−0,+0)\text{Object.is}(-0, +0)Object.is(0,+0) → false.
Кратко: избегайте =ˉ\===ˉ без крайней необходимости — предпочитайте явные преобразования и =ˉ=\====ˉ=.
1 Июн в 14:47
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир