Чем отличается != от !== в JavaScript (и == от ===)?
Читаю чужой код и вижу то ==, то ===, то !=, то !==. В одном месте сравнение проходит, в другом — нет, хотя значения вроде похожи. В чём практическая разница между двумя и тремя символами? И что лучше использовать по умолчанию?
2 ответа
Разница в одном слове: приведение типов.
==и!=— нестрогие: перед сравнением JS пытается привести операнды к одному типу.===и!==— строгие: типы должны совпадать, иначе результат сразуfalse(для===).
Значит != — это «не равно с приведением», а !== — «не равно по значению И типу».
console.log(0 == ''); // true — '' приводится к 0
console.log(0 == '0'); // true — '0' -> 0
console.log('' == '0'); // false — обе строки, '' !== '0'
console.log(null == undefined); // true — специальное правило
console.log(0 == false); // true — false -> 0
console.log(0 === ''); // false — number vs string
console.log(0 !== ''); // true
Именно из-за этих неочевидных приведений == цепочка получается нетранзитивной ('' == 0 и '0' == 0, но '' != '0').
Таблица для интуиции:
| Выражение | == |
=== |
|---|---|---|
0 == '' |
true | false |
0 == '0' |
true | false |
null == undefined |
true | false |
1 == true |
true | false |
NaN == NaN |
false | false |
Рекомендация: всегда используйте === и !==. Так сравнение предсказуемо и не зависит от скрытых преобразований. Единственное оправданное исключение — проверка x == null, которая ловит и null, и undefined одной строкой. Во всех остальных случаях строгое сравнение спасёт от часов отладки.
Маленькая шпаргалка, как это запомнить: количество символов = строгость.
- Два символа (
==,!=) — «мягкие», JS подгоняет типы под друг друга. - Три символа (
===,!==) — «жёсткие», ничего не подгоняют.
Отдельно стоит держать в голове, что NaN не равен ничему, даже самому себе — ни через ==, ни через ===. Для проверки на NaN используйте Number.isNaN(x), а не сравнение.