This is because when any operand of the equivalence operator is a number, in almost all cases the other operand is converted to a number, and then the result is compared. So you end up comparing 1 with 2 , not true with true . The only exceptions for this rule are null , undefined and objects whose default value (see below): null or undefined ; comparing the number with the returned values false (even if Number(null) is 0 , do not ask).
Details in the specification , section 11.9.3: "Abstract equality comparison algorithm" ( HTML version ):
Comparing x == y , where x and y are values, returns true or false . Such a comparison is performed as follows:
If type ( x ) matches type ( y ), then
If type ( x ) is Undefined, return true .
If type ( x ) is Null, return true .
If Type ( x ) is Number, then
If x is NaN , return false .
If y is NaN , return false .
If x is the same numeric value as y , return true .
If x is +0 and y is -0 , return true .
If x is -0 and y is +0 , return true .
Returns false .
If Type ( x ) is a String, return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return <B> false.
If type ( x ) is boolean, return true if x and y are true or both false . Otherwise, return false .
Returns true if x and y refer to the same object. Otherwise, return false .
If x is null and y is undefined , return true .
If x is undefined and y is null , return true .
If Type ( x ) is Number and Type ( y ), it is String, return the result of the comparison x == ToNumber ( y ).
If type ( x ) is a string and type ( y ) is Number,
return comparison result ToNumber ( x ) == y .
If type ( x ) is Boolean, return the result of the comparison ToNumber ( x ) == y .
If type ( y ) is Boolean, return the result of the comparison x == ToNumber ( y ).
If Type ( x ) is either a string or a number and type ( y ), Object,
returns the result of the comparison x == ToPrimitive (<i> y).
If Type ( x ) is Object and Type ( y ), then it is either String or Number,
returns the result of the comparison ToPrimitive ( x ) == y .
Return false .
If you want to verify that they are both true or false, you can use the bang ( ! ) Or double-bang ( !! ) icon to force both of them to booleans:
var a = true, b = 2; alert(a == b); // "false", 1 !== 2 alert(!!a == !!b); // "true", true === true alert(!a == !b); // "true", false === false a = false; b = 0; alert(a == b); // "true", 0 === 0 alert(!!a == !!b); // "true", false === false alert(!a == !b); // "true", true === true
... but usually using == or != with boolean values ββis not ideal. But it really has come.
I tend to use double punch, but in JavaScript there is no reason to break. (There is an argument for double over a single in some other languages, although it is weak due to consistency with if (!!x) . In JavaScript, you never need a double hack in the case of if (x) , so ...)
(Off-topic: the default value for most JavaScript objects is a string, but often like "[object Object]", which ends with NaN if you convert it to a number, but constructor functions can override this behavior with valueOf and toString . The default value for host objects depends on the host environment.)