Was just doing some testing and I find this odd:
[] == false
Gives true, this makes sense because double equal only compares contents and not t
Type conversion is not related to falsy and truthy values.
What is truthy and what is falsy is defined by the ToBoolean function defined in the specs and []
is indeed truthy.
On the other hand, [] == false
returns true
because of the type conversion that happens during the evaluation of the expression.
The rules of type conversion say that for x == y
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
ToNumber results in 0 for false so we're left with the evaluation of [] == 0
. According to the same rules
If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
ToPrimitive results in an empty string. Now we have "" == 0
. Back to our type conversion rules
If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
ToNumber results in 0 for ""
so the final evaluation is 0 == 0
and that is true
!
"Is false" (even with coercion) is different from "evaluates as false in boolean context." obj == false
asks if the object is the boolean value false
, not whether it would evaluate as such if evaluated in boolean context.
You can evaluate an object in boolean context with (!!obj)
.
[] == false; // true
(!![]) == false; // false
"\n " == false; // true
(!!"\n ") == false; // false
from the ECMA-262 5.1 (page 83):
If ToBoolean(lval) is true, return lval
[] || false; // []