Skip to main content

Нестроге (==) проти строгого (===) порівняння

==, це нестроге порівняння, яке спершу приводить операнди до спільного типу, а ===, це строге порівняння, яке вимагає однакового типу і однакового значення. Різниця в одному символі змінює результат: 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 і '' її не проходять.
  • Плутають == з =. Одинарний знак, це присвоєння всередині умови, і воно завжди «істинне» для ненульового значення.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.