6
var arr = [];
Boolean(arr) // true
Boolean(!arr) // false
arr == arr // true
arr == !arr // true ??? what ???

I do not want to get the answer that 'recommend using === instead of =='. I would like to know the reason for this phenomenon and the principle of type conversion of JavaScript.

Ry-
  • 218,210
  • 55
  • 464
  • 476
msm082919
  • 617
  • 8
  • 24

2 Answers2

11

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.

Hamms
  • 5,016
  • 21
  • 28
0

Double equals, ==, performs an amount of type coercion on values before attempting to check for equality.

So arr == arr returns true as you'd expect as what you are actually checking is if [] == [] and both sides of the equation are of the same type.

arr == !arr is actually checking if [] == false. The == then performs type coercion on the [] value. This does not, as Hamms pointed out, perform a boolean conversion, instead [] is turned into a primitive, which is an empty string due to reasons. So now our equation is '' == false. The types on the two sides of this operation are still not the same. So the type coercion kicks in again, and due to truthy and falsey values in javascript, '' also evaluates to false. The equation now becomes false == false, which is obviously true.

EmandM
  • 922
  • 6
  • 12
  • 1
    why `[] also evaluates to false`? If this statement is correct why `Boolean([])` returns true – Isaac Jul 27 '18 at 01:08
  • if ( [ ] ) { //this code run }. why `[ ] == false // true`? – msm082919 Jul 27 '18 at 01:14
  • 1
    That's not quite accurate; you're right in that the case boils down to checking `[] == false`, but in this case JS will actually convert the first operand to its `ToPrimitive` value, not its `ToBoolean` value, and the primitive of an empty array is actually the empty _string_ – Hamms Jul 27 '18 at 01:16
  • The newly edited “truthy and falsy” part is still wrong – string == boolean doesn’t use truthiness of the string, but instead compares them numerically. Try `'x' == true`, or `'0' == false`. – Ry- Jul 27 '18 at 01:31
  • Cheers for the pointers, Hamms answer is a much more complete answer than this one. – EmandM Jul 27 '18 at 01:34