There are two pieces to this puzzle: floating-point numbers and type-insensitive comparison using ==
.
First, 475957E-8905
evaluates as the floating point number 475957 * 10 ^ -8905
, which is incredibly small; in floating-point terms, it's the same as 0
due to the precision limitations of javascript. So, eval("475957E-8905")
returns 0
.
Now, for the second piece of the puzzle.
The ==
means that the types don't have to match, so nodejs (like any JavaScript engine) tries to convert one of them so it can compare them.
Since eval("475957E-8905")
returned 0
, it tries to convert "475957E-8905"
to an integer as well. As we have seen, that is also 0
. Thus, the comparison is 0 == 0
, which is true.
Note that the same thing happens if you do eval("3") == "3"
or eval("3") == 3
-- in each case, the strings are converted to numbers and compared.
Avoiding this problem
You can force a type-sensitive comparison like this:
eval("475957E-8905") === "475957E-8905"
which returns false, because the ===
tells the javascript engine to return true only if the types and the values both match.