Why is [] == ![] true in JavaScript?
Type conversion in JS, particularly with regards to loose equality, is a tricky beast.
The best place to always start when answering the question "why does this particular loose equality evaluate this way" is to consult this table of equality comparisons by operand type.
In this case, we can see that for [] == false
, Operand A is an Object and Operand B is a Boolean, so the actual comparison performed is going to be ToPrimitive(A) == ToNumber(B)
.
The right side of that is simple; ToNumber(false)
evaluates to 0
. Done and done.
The left side is more complex; you can check the official ECMAScript spec for full documentation of ToPrimitive
, but all you really need to know is that in this case it boils down to A.valueOf().toString()
, which in the case of the empty array is simply the empty string ""
So, we end up evaluating the equality "" == 0
. A String/Number ==
comparison performs ToNumber
on the string, and ToNumber("")
is 0
, so we get 0 == 0
, which is of course true
.