Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conflicting boolean values of an empty JavaScript array

Tags:

javascript

Can anyone explain why the following two statements both evaluate as true?

[] == false 

and

!![] 

This question is purely out of curiosity of why this happens and not about how to best test if an array is empty.

like image 293
Matthew Manela Avatar asked Nov 19 '10 14:11

Matthew Manela


2 Answers

The first one:

[] == false 

The == operator does type conversion to its operands, in this case the both sides are converted to Number, the steps taken on the Abstract Equality Comparison Algorithm would be:

  • object == boolean
  • object == number
  • string == number
  • number == number

In code:

[] == false; // convert false to Number [] == 0;     // convert [] to Primitive (toString/valueOf) "" == 0;     // convert "" to Number 0  == 0;     // end 

The second comparison, [] is converted to primitive, their valueOf and toString methods are executed, but since valueOf on Array objects, returns the object itself (is inherited from Object.prototype), then the toString method is used.

At the end as you see, both operands are converted to Number, and both yield zero, for example:

Number([]) == 0; Number(false) == 0; 

And empty array produces zero when converted to Number because its string representation is an empty string:

[].toString(); // "" 

And an empty string converted to Number, yields zero:

+""; // 0 

Now, the double negation (!![]) produces true because all object instances are truthy:

![];  // false, [] is truthy !![]; // true, negation 

The only values that are falsey are:

  • null
  • undefined
  • 0
  • NaN
  • "" (an empty string)
  • false

Anything else will produce true when converted to Boolean.

See also:

  • JavaScript Coercion Tool
like image 112
Christian C. Salvadó Avatar answered Sep 22 '22 09:09

Christian C. Salvadó


[] == false

In this case, the type of the left-hand side is object, the type of the right-hand side is boolean. When object is compared to (== The Abstract Equality Comparison) boolean, Javascript first converts the boolean to a number, yielding 0. Then it converts the object to a "primitive", yielding the empty string "". Next it compares the empty string to 0. The empty string is converted to a number, yielding 0, which is numerically equal to the 0 on the right-hand side, so the result of the entire expression is true.

Ref: http://es5.github.com/#x11.9.3 11.9.3 The Abstract Equality Comparison Algorithm

!![]

In this case Javascript converts the object to the boolean true, then inverts it, resulting in false.

like image 36
goobingo Avatar answered Sep 19 '22 09:09

goobingo