As the title states, why does:
> !!1==\"1\"
equal
True
and
> !!2==\"2\"
tldr; this is due to the [ToNumber] conversions in the ==
operator algorithm.
The first step is to simplify the expression. Since !!x=="x"
is parsed like (!!x)=="x"
and !!a_truthy_expression -> true
, the actual relevant expression for the equality is
!!1=="2" -> true=="1" -> Boolean==String
!!2=="2" -> true=="2" -> Boolean==String
So then looking at the rules for 11.9.3 The Abstract Equality Comparison Algorithm and following along with the application yields
Rule 6 - If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
which results in Number==String
or 1=="1" and 1=="2", respectively1. Then the rule
Rule 7 - If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
is applied which results in Number==Number
or 1==1 and 1==2, respectively1; the latter is clearly false.
Rule 1 - If Type(x) is the same as Type(y), then [by c.iii.] If x is the same Number value as y, return true [else return false].
(The same algorithm explains the String==Boolean
case when the complementing rules are applied.)
1To see the [ToNumber] rule applied, consider:
+false -> 0
+true -> 1
+"1" -> 1
+"2" -> 2