KBS
KBS

Reputation: 69

JavaScript seems to evaluate an invalid result when comparing two values

If I write the following code:

" \t\r\n" == 0

JavaScript will return true. However, if I manually convert both values to boolean, then:

!!" \t\r\n" // returns true
!!0 // returns false

That's mean JavaScript says that true == false in the first expression, but the opposite if I compare values converted to boolean, which doesn't make any sense to me.

Please note that I don't write !!"0" but !!0 instead - big difference.

Upvotes: 1

Views: 69

Answers (2)

adeneo
adeneo

Reputation: 318162

The comparison

" \t\r\n" == 0

is true because the specification for the language says it should be true.

Lets start with the algorithm for Abstract Equality Comparison (x == y)

If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

See what it says there, if the first one is a string, which it is, and the second one is a number, which it is, convert the first one to a number based on the ToNumber() operation.

So what's the ToNumber() operation, here it is in the spec

ToNumber applied to Strings applies the following grammar to the input String.
If the grammar cannot interpret the String as an expansion of StringNumericLiteral, then the result of ToNumber is NaN.

The entire chapter on how different strings are converted with ToNumber is pretty complicated, but a little further down in the spec is says

The MV of StringNumericLiteral ::: [empty] is 0.
The MV of StringNumericLiteral ::: StrWhiteSpace is 0.

(MV = Mathematical Value)

So any string that is empty, or just contain whitespace, is converted to 0.

Lets just try and coerce the string ourselves

console.log( +" \t\r\n" ); // gives the number 0

So a string containing a whitespace, a tab, and a newline, is converted to 0.

So, converting the string " \t\r\n" with the internal ToNumber() operation gives the browser 0, so naturally 0 == 0 is true, and that's the answer.

Upvotes: 1

danillouz
danillouz

Reputation: 6371

First of all you're using equality and not strict equality to compare two values.

When using == (equality) values will be coerced. This won't happen when using === (strict equality).

" \t\r\n" == 0 // returns true, these values are 'falsy', which are coerced to false 

" \t\r\n" === 0 // returns false

See this question for reference.

Upvotes: 0

Related Questions