В чем разница между строгим и нестрогим сравнением в JavaScript и почему лучше использовать строгое?
Что проверяют
Понимаете ли вы, что нестрогое сравнение приводит типы по неочевидным правилам, и знаете ли единственное исключение из правила «всегда ===».
Как отвечать
=== сравнивает без приведения типов: разные типы значит не равны. == сначала приводит операнды к общему типу по алгоритму из спецификации, и правила там не интуитивные:
"" == 0 // true
"0" == 0 // true
"" == "0" // false, хотя оба равны нулю
null == 0 // false
null == undefined // true
[] == false // trueИз первых трёх строк видно главное: нестрогое равенство не транзитивно, а значит его нельзя держать в голове как правило. Отсюда практика использовать === всегда, и линтер eqeqeq включён почти во всех наборах правил.
Единственное общепринятое исключение это value == null: такая проверка истинна ровно для null и undefined и ни для чего больше. Она короче, чем value === null || value === undefined, и именно поэтому линтеры разрешают её отдельным флагом.
Полезно добавить про Object.is: он почти как ===, но NaN равен самому себе, а +0 и -0 различаются. Пригождается в сравнении значений и лежит в основе сравнения зависимостей в React.
И про объекты: и ==, и === сравнивают их по ссылке. Два одинаковых по содержимому объекта не равны, для сравнения по значению нужна своя функция.
Где спотыкаются
Используют == для сравнения строки с числом «чтобы не приводить типы вручную».
Не знают идиому == null.
Считают, что NaN === NaN истинно.
Сравнивают объекты через === и ждут сравнения по содержимому.