Consider empty JavaScript array:
var a = [];
alert(a == false); // shows true
alert(!a); // shows false!
How to explain this? What are the
From http://forums.whirlpool.net.au/archive/966449:
a == false
:
In this case, the type of the left-hand side is object, the type of the right-hand side is 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
.
See §11.9.3 of the ECMAScript spec for all the gory details.
(!a)
:
In this case Javascript converts the object to the boolean true, then inverts it, resulting in false.
The ==
operator when one of the operands if Boolean, type-converts the other to Number.
[] == 0;
Is equivalent to:
0 == 0;
You can see the complete details of The Abstract Equality Comparison Algorithm on the specification.
As you can see, an empty array object, when converted to Number, produces 0
:
+[]; // 0
Number(0);
This is really because its toString method produces an empty string, for example:
[].toString(); // ""
+""; // 0
Number(""); // 0
The !
operator checks whether its operand is "falsy".
The following are true:
!false
!0
!null
!NaN
!undefined
!""
The ==
operator checks for loose equality, which has nothing to do with falsiness.
Specifically, a == b
will convert to operands to numbers, then compare the numbers.
Strings containing numbers convert to the numbers that they contain; booleans convert to 0
and 1
.
Objects are converted by calling valueOf
, if defined.
Thus, all of the following are true:
"1" == 1
"0" == false
"1" == true
"2" != true
"2" != false
({ valueOf:function() { return 2; } }) == 2
({ valueOf:function() { return 1; } }) == true
When comparing an object to a primitive value via the ==
operator, the object coerces into an primitive value itself (number or string). In this case []
coerces into 0
, then false
coerces into 0
:
[] == false
0 == false
0 == 0
which is true.
The !
operator coerces into boolean and then inverts the value. []
into boolean is true
(like with any object). Then invert to become false
![]
!true
false
Not sure if this answers the question, but there is a new library for getting around all of Javascript's Typecasting weirdnesses:
Typecast.js
In a sentence, Typecast solves all the simple problems, so you can focus on the big ones. Typecast fixes what's wrong with Javascript by creating a complete platform for strongly-typed variables in Javascript.