# == vs === Equality Operators in JavaScript: Understanding the Difference

> Discover the crucial difference between JavaScript's == and === equality operators. Learn how type coercion impacts comparisons and why === offers predictable, strict equality for your code.

- Repository: [Lydia Hallie/javascript-questions](https://github.com/lydiahallie/javascript-questions)
- Tags: deep-dive
- Published: 2026-03-04

---

**The `==` operator performs type coercion before comparing values, while `===` checks both value and type without coercion, making strict equality the preferred choice for predictable comparisons.**

JavaScript provides two distinct ways to compare values: the abstract equality operator (`==`) and the strict equality operator (`===`). Understanding the difference between these equality operators is fundamental to writing reliable code, as detailed in the [lydiahallie/javascript-questions](https://github.com/lydiahallie/javascript-questions) repository. While both operators appear similar, their behavior regarding type coercion creates significantly different outcomes in practice.

## How Abstract Equality (==) Performs Type Coercion

The abstract equality operator (`==`) performs **type coercion** before comparing values. When operands have different types, JavaScript attempts to convert one or both values to a common type, then checks if the resulting values are equal.

According to the source code in [[`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md)](https://github.com/lydiahallie/javascript-questions/blob/master/README.md), the `==` operator "only checks whether it has the same *value*"【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/lydiahallie/javascript-questions/master/README.md#L272】. This conversion logic can produce unintuitive results. For example, `0 == false` evaluates to `true` because the boolean `false` is coerced to the number `0` before comparison.

## How Strict Equality (===) Checks Value and Type

The strict equality operator (`===`) **never** performs type coercion. It returns `true` only when both the value and the type of the operands are identical.

As implemented in `lydiahallie/javascript-questions`, the README explains that `===` "checks both value *and* type"【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/lydiahallie/javascript-questions/master/README.md#L274】. For instance, `0 === false` returns `false` because the types differ (`number` versus `boolean`). Similarly, comparing a wrapper object to a primitive fails under strict equality: `new Number(3) === 3` evaluates to `false` because one is an object and the other is a primitive number.

## Code Examples: == vs === in Practice

The repository provides concrete examples demonstrating these behavioral differences in [[`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md)](https://github.com/lydiahallie/javascript-questions/blob/master/README.md)【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/lydiahallie/javascript-questions/master/README.md#L255-L257】:

```javascript
// Abstract equality (type coercion)
let a = 3;
let b = '3';
console.log(a == b);   // true – b is coerced to a number

// Strict equality (no coercion)
console.log(a === b);  // false – different types (number vs. string)

// Object vs. primitive
let c = new Number(3);
console.log(c == 3);   // true  – object is coerced to primitive
console.log(c === 3);  // false – different types (object vs. number)

```

These examples illustrate why strict equality produces more predictable results. When comparing the string `'3'` to the number `3`, abstract equality returns `true` due to coercion, while strict equality correctly identifies them as different types.

## Summary

- **`==` (Abstract Equality)** converts operands to a common type before comparison, which can lead to unexpected truthy evaluations like `0 == false`.
- **`===` (Strict Equality)** requires both value and type to match exactly, eliminating implicit conversion surprises.
- The [`lydiahallie/javascript-questions`](https://github.com/lydiahallie/javascript-questions) repository documents these behaviors extensively in [`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md) to help developers avoid common pitfalls.
- **Best Practice:** Use `===` for all comparisons unless you explicitly require the type-coercion behavior of `==` and have accounted for edge cases.

## Frequently Asked Questions

### Why does 0 == false return true but 0 === false returns false?

Under abstract equality (`==`), JavaScript coerces the boolean `false` to the number `0` before comparison, making them equal. As documented in the repository's [`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md), the operator checks only for matching values after coercion【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/lydiahallie/javascript-questions/master/README.md#L272】. Strict equality (`===`) returns `false` immediately because the types differ—`0` is a number while `false` is a boolean.

### Can == and === produce different results with strings and numbers?

Yes. When comparing a string to a number, `==` converts the string to a number first. For example, `'3' == 3` evaluates to `true` because the string `'3'` coerces to the number `3`. In contrast, `'3' === 3` returns `false` because no type coercion occurs and the operands have different types (string versus number), as shown in the code examples at [[`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md)](https://github.com/lydiahallie/javascript-questions/blob/master/README.md)【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/lydiahallie/javascript-questions/master/README.md#L255-L257】.

### How do == and === handle wrapper objects like new Number()?

Abstract equality coerces wrapper objects to their primitive values, so `new Number(3) == 3` returns `true`. However, strict equality checks both value and type without coercion, causing `new Number(3) === 3` to return `false` because the left operand is an object while the right is a primitive number. The README highlights this distinction to demonstrate why `===` provides more predictable type checking【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/lydiahallie/javascript-questions/master/README.md#L274】.

### Which equality operator should I use in production code?

The repository recommends using **strict equality (`===`)** as the default choice because it avoids implicit type conversions and produces clearer, more predictable code. Reserve abstract equality (`==`) for specific scenarios where you explicitly require type coercion and have thoroughly tested all edge cases, such as checking for both `null` and `undefined` simultaneously.