... but I'm trying to understand the rationale. MDN says:
The equality operator converts the operands if they are not of the
same type, then applies strict comparison. If both operands are
when operands refer to the same object in memory.
"0" == false // which is true
Boolean("0") == false
"0" == false
The specification isn't a general "let's do what seems natural" rule, it is made of a sequence of simple rules. Let's apply it, you'll see that your assumption isn't verified:
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
false is converted to a number and it's
0 (you can check
+false in the console).
If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
"0" is compared to
0, which is done by converting
If you're looking for a global rational of abstract equality among defined values, I'd say it is to prefer numbers, then strings.
As for the second check,
Boolean("0") == false, it's simpler: the
Boolean function converts to
true anything that isn't falsy (