As per the Operator precedence rules, logical ! has higher priority over == . So, in both the cases, !! is evaluated first.

Note: Truthiness of various objects have been explained in this answer of mine.

First Case

!!1 == "1"

!1 will be evaluated to false , since 1 is considered Truthy. Negating again we get true . So the expression becomes

true == "1"

Now, the coercion rules kick in as you have used == operator, which evaluates as per the The Abstract Equality Comparison Algorithm defined in ECMAScript 5.1 Specification,

6. If Type(x) is Boolean , return the result of the comparison ToNumber(x) == y .

So, true will be converted to a number, which is 1 as per ToNumber algorithm for Boolean values. Now the expression becomes

1 == "1"

Now,

4. If Type(x) is Number and Type(y) is String , return the result of the comparison x == ToNumber(y) .

So, "1" will be converted to a number and that will give 1, as per the ToNumber algorithm. That is why it shows true in the first case.

Second Case

The same rules are applied here.

!!2 == "2"

becomes

true == "2"

then

1 == "2"

which becomes

1 == 2