This behaviour might be surprising but can be explained by having a look at the specification.
We have to look at the what happens when a comparison with the equals operator is performed. The exact algorithm is defined in section 11.9.3.
I built a simple tool to demonstrate which algorithm steps are executed: https://felix-kling.de/js-loose-comparison/
string == integer
The step we have to look at is #5:
5. If Type(x)
is String and Type(y)
is Number,
return the result of the comparison ToNumber(x) == y
.
That means the string "
"
("
"
, ""
) is converted to a number first and then compared against 0
.
How is a string converted to a number? This is explained in section 9.3.1. In short, we have:
The MV (mathematical value) of StringNumericLiteral ::: StrWhiteSpace
is 0
.
where StrWhiteSpace
is defined as
StrWhiteSpace :::
StrWhiteSpaceChar StrWhiteSpace_opt
StrWhiteSpaceChar :::
WhiteSpace
LineTerminator
This just means that the numerical value of strings containing white space characters and/or a line terminator is 0
.
Which characters are considered as white space characters is defined in section 7.3.
string == boolean
The step we have to look at is #7:
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y)
.
How booleans are converted to numbers is pretty simple: true
becomes 1
and false
becomes 0
.
Afterwards we are comparing a string against a number, which is explained above.
As others have mentioned, strict comparison (===
) can be used to avoid this "problem". Actually you should only be using the normal comparison if you know what you are doing and want this behaviour.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…