Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Нестроге (==) проти строгого (===) порівняння». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`==` порівнює значення після неявного приведення типів, а `===` порівнює і тип, і значення без жодних перетворень.** Саме тому `5 == '5'` дає `true`, а `5 === '5'` дає `false`. Нестроге порівняння тягне за собою довгий список правил приведення, через які легко отримати неочікуваний результат на даних від користувача чи з API. ```javascript 5 == '5'; // true, рядок '5' перетворюється на число 5 5 === '5'; // false, різні типи ``` **Ключове:** завжди пишіть `===` і `!==`, окрім свідомої перевірки `value == null`, яка ловить одразу `null` і `undefined`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`==`, це нестроге порівняння, яке спершу приводить операнди до спільного типу, а `===`, це строге порівняння, яке вимагає однакового типу і однакового значення.** Різниця в одному символі змінює результат: `0 == false` дає `true`, а `0 === false` дає `false`. ## Теорія ### TL;DR - `==` перетворює типи перед порівнянням, `===` не перетворює нічого. - Для `===` результат `true` можливий лише тоді, коли тип і значення збігаються. - `null == undefined`, це `true`, але `null === undefined`, це `false`. - Правила приведення в `==` неочевидні, тому саме на них народжуються баги з даними від користувача або з API. - Стандарт де-факто: усюди `===` і `!==`, а `==` лише у формі `value == null`. ### Швидкий приклад ```javascript console.log(5 == '5'); // true, типи приведено console.log(5 === '5'); // false, число проти рядка console.log(0 == false); // true, false стає 0 console.log(0 === false); // false, число проти булевого значення ``` ### Оператор `==`, нестроге (абстрактне) порівняння `==` перетворює типи операндів перед порівнянням. Тобто JavaScript намагається «вгадати», чи рівні значення після приведення типів. **Приклади:** ```javascript 5 == '5' // true -> рядок '5' перетворюється на число 5 0 == false // true -> false приводиться до 0 null == undefined // true -> це єдиний випадок, коли вони рівні ' ' == 0 // true -> рядок із пробілів перетворюється на 0 ``` > Небезпека: через неявні перетворення часто трапляються помилки, особливо під час перевірок користувацького введення або даних з API. ### Оператор `===`, строге порівняння `===` не робить перетворень типів. Операнди мають бути однакового типу і значення, щоб результат був `true`. **Приклади:** ```javascript 5 === '5' // false -> різні типи (число і рядок) 0 === false // false -> різні типи null === undefined // false -> різні типи 5 === 5 // true -> однакове значення і тип ``` ### Як саме `==` приводить типи Порядок правил короткий, але його майже ніхто не пам'ятає напам'ять, і це головний аргумент проти `==`: 1. Якщо типи однакові, працює звичайне строге порівняння. 2. `null` і `undefined` рівні одне одному і більше нічому. 3. Число проти рядка: рядок перетворюється на число. 4. Булеве значення з будь-якого боку спершу стає числом (`true` дає 1, `false` дає 0). 5. Об'єкт проти примітива: об'єкт зводиться до примітива через `valueOf()` або `toString()`. ```javascript [] == false; // true, [] стає '', потім 0, а false теж 0 [1] == 1; // true, [1] стає '1', потім 1 '0' == false; // true, обидва зводяться до 0 '0' === false; // false ``` Обидва оператори однаково не рятують у двох особливих випадках: `NaN` не дорівнює самому собі, а `+0` і `-0` вважаються рівними. Для цих ситуацій є `Object.is()`. ```javascript NaN === NaN; // false Object.is(NaN, NaN); // true Object.is(0, -0); // false ``` ### Підсумок: коли що використовувати | Оператор | Приводить типи | Типове застосування | | --- | --- | --- | | `===` / `!==` | ні | майже завжди, стандарт для будь-яких перевірок | | `==` / `!=` | так | лише свідомо, у вигляді `value == null` | | `Object.is()` | ні | коли важливо розрізнити `NaN` і знак нуля | Рекомендація: завжди використовуйте `===` (і `!==`), якщо немає особливої причини застосувати нестроге порівняння. Це робить код передбачуваним і знижує кількість багів. Виняток, який лишають навіть суворі лінтери, це перевірка `if (value == null)`, бо вона коротко покриває і `null`, і `undefined`. ### Типові помилки - **Перевіряють дані з форми чи API через `==`.** Введення завжди приходить рядком, тож `'0' == false` дає `true` і умова спрацьовує не так, як задумано. - **Вважають, що `===` порівнює вміст об'єктів.** Для об'єктів обидва оператори порівнюють посилання: `{} === {}`, це `false`. - **Пишуть `x == NaN`.** Жодне порівняння з `NaN` не дасть `true`, потрібен `Number.isNaN(x)`. - **Використовують `== null` не розуміючи, що робиться.** Це навмисна перевірка одразу на `null` і `undefined`, а не «менш строга» версія перевірки на порожнечу: `0` і `''` її не проходять. - **Плутають `==` з `=`.** Одинарний знак, це присвоєння всередині умови, і воно завжди «істинне» для ненульового значення.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.