Skip to main content

Why [] == false returns true

[] == false returns true because loose comparison makes JavaScript coerce both sides to a number, and it ends up comparing 0 == 0. Along the way the array becomes an empty string and the empty string becomes zero, so the equality turns out to be true even though nothing meaningful is equal here.

Theory

TL;DR

  • == triggers type coercion, === does not.
  • A boolean operand in a == comparison is always turned into a number first: false is 0.
  • An object (and an array is an object) is coerced to a primitive through valueOf(), then toString().
  • [].toString() gives the empty string '', and Number('') gives 0.
  • So the expression reduces to 0 == 0, which is true.
  • [] === false is false, because strict comparison performs no coercion.

Quick example

javascript
console.log([] == false); // true console.log([] === false); // false // The same chain, written out by hand: console.log(Number(false)); // 0 console.log([].toString()); // '' console.log(Number('')); // 0 console.log(0 == 0); // true

Step by step explanation

Take the expression:

javascript
[] == false

Step 1. == triggers type coercion. In a loose comparison JS tries to coerce the types so that the comparison becomes possible. The abstract equality algorithm in the ECMAScript specification states the rule as:

If one of the operands is of type boolean, it is converted to a number.

Step 2. Convert false to a number.

javascript
false -> 0

Now the expression looks like this:

javascript
[] == 0

Step 3. An object (an array) on the left, a primitive on the right. If one of the operands is an object, it is first coerced to a primitive (through valueOf(), then toString()). For the array []:

javascript
[].toString(); // ''

So:

javascript
[] -> '' // empty string

And now we have:

javascript
'' == 0

Step 4. Comparing '' == 0. By the same algorithm:

If one operand is a string and the other is a number, the string is converted to a number.

javascript
Number('') -> 0

So:

javascript
0 == 0

The result:

javascript
true

Summary of the steps

StageExpressionWhat happened
1[] == falsefalse -> 0
2[] == 0[] -> ''
3'' == 0'' -> 0
40 == 0true

Why this is dangerous

This logic makes == unpredictable. Here are more examples of the same mechanism:

javascript
[] == ![] // true '' == 0 // true '0' == 0 // true null == undefined // true [] == '' // true [0] == 0 // true [1] == 1 // true [2] == 2 // true

The first line is the most telling one: ![] is false (an array is always truthy, so negating it gives false), then the familiar chain runs and [] == ![] also becomes true. A value equals its own negation, and that is perfectly legal JavaScript.

How to avoid the confusion

Use strict comparison ===, which performs no implicit type conversion.

javascript
[] === false // false '' === 0 // false null === undefined // false

A short recap:

ExpressionWhat JS doesResult
[] == false[] -> '' -> 0, false -> 0true
[] === falseCompares without coercionfalse

If you need to check whether an array is empty, check it explicitly:

javascript
if (items.length === 0) { // empty array }

Common mistakes

  • Checking an array for emptiness by comparing it with false or 0. It works by accident and breaks as soon as the value becomes null or an object. Check items.length === 0 instead.
  • Reading [] == false as "an array is falsy". An empty array is in fact truthy: the body of if ([]) runs. The falsiness here appears only because == coerces it to a number.
  • Mixing up == and === in null checks. Here == is occasionally useful: x == null catches both null and undefined. But that is the one exception, and it should be used deliberately.
  • Relying on valueOf() for arrays. For a plain array valueOf() returns the array itself, which is not a primitive, so the engine falls through to toString(). Override valueOf() and the comparison result changes.
  • Ignoring the linter. The ESLint eqeqeq rule bans == precisely because of cases like this, and turning it off for "shorter code" is not worth it.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.