Today when I was doing some experiments with ==
, I accidentally found out that "\n\t\r" == 0
. How on earth does "\n\t\r"
equal to 0
, or false
?
What I did is:
var txt = "\n"; //new line txt == 0; //it gives me true
And that really annoy me. So I did more:
var txt = "\r"; //"return" txt == 0; //true var txt = "\t"; //"tab" txt == 0; //true
It does not make sense, at all. How's that happen? And more crazy is this:
//Checking for variable declared or not var txt ="\n\t\r"; if(txt!=false){ console.log("Variable is declared."); }else{ console.log("Variable is not declared."); }
What it gives me is Variable is not declared.
How is it equal to 0
, or false
???
Because they don't represent equally convertible types/values. The conversion used by == is much more complex than a simple toBoolean conversion used by if ('true') . So given this code true == 'true' , it finds this: "If Type(x) is Boolean , return the result of the comparison ToNumber(x) == y ."
Just (invisible) entries in a string. \r moves cursor to the beginning of the line. \n goes one line down.
\r is "Carriage Return" (CR, ASCII character 13), \n is "Line Feed" (LF, ASCII character 10).
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 andType(y)
is Number,
return the result of the comparisonToNumber(x) == y
.
That means the string "\n"
("\r"
, "\t"
) 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
is0
.
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.
Because JavaScript is a loosely typed language, it attempts to type cast your 1st side of the comparison to the other so that they would match each other.
Any string which does not contain a number, becomes 0 when compared to an integer, and becomes true (Except in certain situations), when compared to a Boolean.
Light reading material.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With