Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'\n\t\r' == 0 is true?

Tags:

javascript

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???

like image 226
Derek 朕會功夫 Avatar asked Apr 29 '12 21:04

Derek 朕會功夫


People also ask

Why does true == true return 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 ."

What is \r in a string?

Just (invisible) entries in a string. \r moves cursor to the beginning of the line. \n goes one line down.

What is backslash r in JavaScript?

\r is "Carriage Return" (CR, ASCII character 13), \n is "Line Feed" (LF, ASCII character 10).


2 Answers

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 "\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 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.

like image 129
Felix Kling Avatar answered Sep 17 '22 15:09

Felix Kling


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.

like image 28
Madara's Ghost Avatar answered Sep 20 '22 15:09

Madara's Ghost