Because '0' is not equal 1, so it is not equal to true, though it is not false.
In the first case, when '0' is casted to bool, casting operator returns true for everything that is not 0.
0 is a string value, every non-empty string is evaluated as true, and not tested as boolean. If quotes are removed:
(0 ? 'a' : 'b'); /* -> 'b' */
you will receive b - now 0 is not a string and evaluated as false!
('0' == true ? 'a' : 'b'); /* -> 'b' */
0 is evaluated as bool Both are evaluated as numbers, which is false. Point 11.9.3 The Abstract Equality Comparison Algorithm from the specs show that a number of conversions may be executed to compare the same type of variables.