ABGR
ABGR

Reputation: 5205

Why does Number('') returns 0 whereas parseInt('') returns NaN

I have gone through similar questions and answers on StackOverflow and found this:

parseInt("123hui")
returns 123

Number("123hui")
returns NaN

As, parseInt() parses up to the first non-digit and returns whatever it had parsed and Number() tries to convert the entire string into a number, why unlikely behaviour in case of parseInt('') and Number('').

I feel ideally parseInt should return NaNjust like it does with Number("123hui")

Now my next question:

As 0 == '' returns true I believe it interprets like 0 == Number('') which is true. So does the compiler really treat it like 0 == Number('') and not like 0 == parseInt('') or am I missing some points?

Upvotes: 9

Views: 678

Answers (3)

6502
6502

Reputation: 114481

parseInt("") is NaN because the standard says so even if +"" is 0 instead (also simply because the standard says so, implying for example that "" == 0).

Don't look for logic in this because there's no deep profound logic, just history.

You are in my opinion making a BIG mistake... the sooner you correct it the better will be for your programming life with Javascript. The mistake is that you are assuming that every choice made in programming languages and every technical detail about them is logical. This is simply not true.

Especially for Javascript.

Please remeber that Javascript was "designed" in a rush and, just because of fate, it became extremely popular overnight. This forced the community to standardize it before any serious thought to the details and therefore it was basically "frozen" in its current sad state before any serious testing on the field.

There are parts that are so bad they aren't even funny (e.g. with statement or the == equality operator that is so broken that serious js IDEs warn about any use of it: you get things like A==B, B==C and A!=C even using just normal values and without any "special" value like null, undefined, NaN or empty strings "" and not because of precision problems).

Nonsense special cases are everywhere in Javascript and trying to put them in a logical frame is, unfortunately, a wasted effort. Just learn its oddities by reading a lot and enjoy the fantastic runtime environment it provides (this is where Javascript really shines... browsers and their JIT are a truly impressive piece of technology: you can write a few lines and get real useful software running on a gajillion of different computing devices).

The official standard where all oddities are enumerated is quite hard to read because aims to be very accurate, and unfortunately the rules it has to specify are really complex.

Moreover as the language gains more features the rules will get even more and more complex: for example what is for ES5 just another weird "special" case (e.g. ToPrimitive operation behavior for Date objects) becomes a "normal" case in ES6 (where ToPrimitive can be customized).

Not sure if this "normalization" is something to be happy about... the real problem is the frozen starting point and there are no easy solutions now (if you don't want to throw away all existing javascript code, that is).

The normal path for a language is starting clean and nice and symmetric and small. Then when facing real world problems the language gains (is infected by) some ugly parts (because the world is ugly and asymmetrical).

Javascript is like that. Except that it didn't start nice and clean and moreover there was no time to polish it before throwing it in the game.

Upvotes: -1

T J
T J

Reputation: 43156

To answer your question about 0==''returning true :

Below is the comparison of a number and string:

The Equals Operator (==)

Type (x) Type(y)              Result
-------------------------------------------
x and y are the same type      Strict Equality (===) Algorithm
Number  String                 x == toNumber(y)

and toNumber does the following to a string argument:

toNumber:

Argument type    Result
------------------------
String          In effect evaluates Number(string)
                 “abc” -> NaN
                 “123” -> 123

Number('') returns 0. So that leaves you with 0==0 which is evaluated using Strict Equality (===) Algorithm

The Strict Equals Operator (===)

Type            values                        Result
----------------------------------------------------------
Number       x same value as y                true
             (but not NaN)

You can find the complete list @ javascriptweblog.wordpress.com - truth-equality-and-javascript.

Upvotes: 0

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123473

The difference is due in part to Number() making use of additional logic for type coercion. Included in the rules it follows for that is:

  • A StringNumericLiteral that is empty or contains only white space is converted to +0.

Whereas parseInt() is defined to simply find and evaluate numeric characters in the input, based on the given or detected radix. And, it was defined to expect at least one valid character.

13) If S contains a code unit that is not a radix-R digit, let Z be the substring of S consisting of all code units before the first such code unit; otherwise, let Z be S.

14) If Z is empty, return NaN.

Note: 'S' is the input string after any leading whitespace is removed.


As 0=='' returns true I believe it interprets like 0==Number('') [...]

The rules that == uses are defined as Abstract Equality.

And, you're right about the coercion/conversion that's used. The relevant step is #6:

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

Upvotes: 5

Related Questions