To the best of my knowledge, (x == false)
should do the same thing as !x
, as both of them try to interpret x
as a boolean, and then negates it.
However, when I tried to test this out, I started getting some extremely strange behavior.
For example:
false == []
and false == ![]
both return true.
Additionally
false == undefined
and true == undefined
both return false, as does
false == Infinity
and true == Infinity
and
false == NaN
and true == NaN
.
What exactly is going on here?
It's all here: http://es5.github.com/#x11.9.3
For the case of false == []
:
false
is converted to a number (0), because that is always done with booleans. [].valueOf().toString()
, and that is an empty string. 0 == ""
is then evaluated by converting the empty string to a number, and because the result of that is also 0, false == []
is true. For the case of false == ![]
:
!
is performed by returning the opposite of ToBoolean(GetValue(expr))
ToBoolean()
is always true for any object, so ![]
evaluates to false
(because !true = false
), and therefore is false == ![]
also true. (false == undefined) === false
and (true == undefined) === false
is even simpler:
false
and true
are again converted to numbers (0 and 1, respectively). false
. The other two cases are evaluated the same way: First Boolean to Number, and then compare this to the other number. Since neither 0 nor 1 equals Infinity or is Not A Number, those expressions also evaluate to false
.
The abstract equality algorithm is described in section 9.3 of the specification .
For x == y
where x = false
and y = []
:
Repeat the algorithm, x= 0
and y= []
.
We end at step 8:Type(x) == number. and Type(y) == object.
So, let the result be x == ToPrimitive (y).
ToPrimitive([]) == ""
Now, repeat the algorithm again with x= 0
and y= ""
. We end at 4: "return the result of the comparison x == ToNumber(y)."
ToNumber("") == 0
The last repetition of the algorithm ends at step 1 (types are equal). By 1.c.iii, 0 == 0, and true is returned.
The other results can be obtained in a similar manner, by using the algorithm.
false == []
Using ==
Javascript is allowed to apply conversions. The object will convert into a primitive to match type with the boolean, leaving an empty string. The false will convert into a number 0. The compares the empty string and the number 0. The string is converted to a number which will be 0, so the expression is "true"
![]
Javascript converts the object to the boolean true, therefore denying true ends being false.
false == undefined true == undefined
false == Infinity and true == Infinity
false == NaN and true == NaN
Again a bit of the same! false is converted to 0, true to 1. And then, undefined is converted to a number which is... NaN! So false in any case
I would recommend to use === !==
as much as you can to get "expected" results unless you know very well what you are doing. Using something like Boolean(undefined) == fals
e would also be nice.
Check ECMAScript specifications for all the details when converting stuff.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.