Suggest an editImprove this articleRefine the answer for “Loose (==) vs strict (===) equality in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`==` compares values after implicit type coercion, while `===` compares both type and value with no conversion at all.** That is why `5 == '5'` is `true` but `5 === '5'` is `false`. Loose equality drags in a long list of coercion rules that make unexpected results easy to hit on user input or API data. ```javascript 5 == '5'; // true, the string '5' is converted to the number 5 5 === '5'; // false, different types ``` **Key point:** always write `===` and `!==`, except for a deliberate `value == null` check, which catches both `null` and `undefined` at once.Shown above the full answer for quick recall.Answer (EN)Image**`==` is loose equality, which first coerces both operands to a common type, while `===` is strict equality, which demands the same type and the same value.** One extra character changes the result: `0 == false` is `true`, but `0 === false` is `false`. ## Theory ### TL;DR - `==` converts types before comparing, `===` converts nothing. - With `===`, a `true` result is only possible when type and value both match. - `null == undefined` is `true`, but `null === undefined` is `false`. - The coercion rules behind `==` are not obvious, which is exactly where bugs with user input or API data come from. - The de facto standard: `===` and `!==` everywhere, and `==` only in the form `value == null`. ### Quick example ```javascript console.log(5 == '5'); // true, the types were coerced console.log(5 === '5'); // false, number versus string console.log(0 == false); // true, false becomes 0 console.log(0 === false); // false, number versus boolean ``` ### The `==` operator, loose (abstract) comparison `==` converts the types of the operands before comparing them. In other words, JavaScript tries to "guess" whether the values are equal after type coercion. **Examples:** ```javascript 5 == '5' // true -> the string '5' turns into the number 5 0 == false // true -> false is coerced to 0 null == undefined // true -> this is the only case where they are equal ' ' == 0 // true -> a whitespace string turns into 0 ``` > The danger: implicit conversions are a frequent source of bugs, especially when checking user input or data coming from an API. ### The `===` operator, strict comparison `===` performs no type conversion. The operands must have the same type and the same value for the result to be `true`. **Examples:** ```javascript 5 === '5' // false -> different types (number and string) 0 === false // false -> different types null === undefined // false -> different types 5 === 5 // true -> same value and same type ``` ### How `==` actually coerces The list of rules is short, yet almost nobody remembers it by heart, and that is the main argument against `==`: 1. If the types match, plain strict comparison runs. 2. `null` and `undefined` are equal to each other and to nothing else. 3. Number versus string: the string is converted to a number. 4. A boolean on either side becomes a number first (`true` gives 1, `false` gives 0). 5. Object versus primitive: the object is reduced to a primitive via `valueOf()` or `toString()`. ```javascript [] == false; // true, [] becomes '', then 0, and false is 0 too [1] == 1; // true, [1] becomes '1', then 1 '0' == false; // true, both are reduced to 0 '0' === false; // false ``` Neither operator helps in two special cases: `NaN` is not equal to itself, and `+0` and `-0` count as equal. `Object.is()` exists for exactly those situations. ```javascript NaN === NaN; // false Object.is(NaN, NaN); // true Object.is(0, -0); // false ``` ### Summary: when to use which | Operator | Coerces types | Typical use | | --- | --- | --- | | `===` / `!==` | no | almost always, the default for any check | | `==` / `!=` | yes | only deliberately, as `value == null` | | `Object.is()` | no | when `NaN` or the sign of zero must be distinguished | Recommendation: always use `===` (and `!==`) unless there is a specific reason for loose comparison. It makes the code predictable and cuts down the number of bugs. The one exception that even strict linters allow is `if (value == null)`, because it covers both `null` and `undefined` in a single short check. ### Common mistakes - **Checking form or API data with `==`.** Input always arrives as a string, so `'0' == false` is `true` and the condition fires in a way nobody intended. - **Assuming `===` compares object contents.** For objects both operators compare references: `{} === {}` is `false`. - **Writing `x == NaN`.** No comparison against `NaN` ever returns `true`, you need `Number.isNaN(x)`. - **Using `== null` without understanding it.** It is a deliberate check for `null` and `undefined` together, not a "less strict" emptiness check: `0` and `''` do not pass it. - **Confusing `==` with `=`.** A single sign is an assignment inside the condition, and it is always truthy for a non-zero value.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.