问题
Was just doing some testing and I find this odd:
[] == false
Gives true, this makes sense because double equal only compares contents and not type and tries to do type-coercion. But if its comparing contents and returns true, that means [ ] is falsey (if you did [] == true
you get false too), which means:
[] || false
Should give false, but it gives [ ], making it truthy? Why?
Another example:
"\n " == 0
Gives true, but "\n " || false
gives "\n "
? Is there an explanation for this or its just an oddity.
When I tried this in C, we get:
int x = "\n " == 0;
printf("%d\n", x);
int y = "\n " || 0;
printf("%d\n", y);
Outputs:
0
1
This makes sense, but given C's influence on Javascript, the behaviour is different.
回答1:
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
!
回答2:
"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
回答3:
from the ECMA-262 5.1 (page 83):
If ToBoolean(lval) is true, return lval
[] || false; // []
来源:https://stackoverflow.com/questions/25272627/if-false-is-true-why-does-true-result-in