JS WTF 🦄 with Number

Time to ride on some JavaScript WTF with Number.

Tiago Ferreira
HackerNoon.com
Published in
4 min readOct 29, 2017

--

‘0.0’

When converting a String into a Number, JS is able to interpret a period before or after a numeric value as the period of a decimal number. That’s why the get 0 as the result for the first two expressions.

Both '0.' and '.0' represent the decimal 0.0.

Here’s the specification:

I know. I know. Too much detail!

However, “if the grammar cannot interpret the String as an expansion of StringNumericLiteral, then the result of ToNumber is NaN.”, which explains the result for Number('.').

i.e. the expression '.' does not match any of the string literals highlighted in the red box above.

{} vs []

When Number is applied to an Object JavaScript tries to convert it to a primitive value.

By specification, it first executes .valueOf().

Because .valueOf() of both {} and [] also return an object, JS tries .toString().

The reason for this WTF lies on the result of .toString().

The operation ({}).toString() actually runs Object.prototype.toString() which by definition is "[object Object]". However, as we saw before, converting a String into a Number returns NaN when it cannot be interpret into a numeric value. This explains out first result Number({}) // NaN.

As for [].toString(), it executes Array.prototype.toString() and outputs "". By definition, Number("") is 0.

Therefore Number([]) is 0.

Ok! Let’s take a break and watch this kitties 👀

undefined vs null

According ToBoolean both null and undefined represent the absence of something, meaning false.

However, we can see undefined as more generic “absence.” This is because it is used to represent a variable’s value when no other value has been assigned.

undefined, a variable has been declared but no formal value has been assigned.

null, on the other hand, is an assignment value. It can be assigned to a variable as a representation of “no value.”

null, a variable has been declared but has an empty value.

Moreover, they have a different typeof.

Because of this I came to believe that this is why undefined is converted into a NaN when executing Number(undefined), meaning no value assigned.

And null to the value 0, meaning a falsy representation of a value.

MIN_VALUE

It’s easy to understand that Number.MAX_VALUE is bigger than 0 but it’s weird to realise that Number.MIN_VALUE is not smaller than 0.

That’s because Number.MIN_VALUE is not actually the minimum value possible, but the minimum positive value possible, which is a very very very small value (5e-324 to be specific), however bigger than 0.

To represent the minimum value possible we can safely use Number.MIN_SAFE_INTEGER i.e. -(2^53–1)

toFixed()

Having a period on a numeric value is the way to say that it has a fractional part. However, this makes the use of static methods inconsistent.

For the expression 42.toFixed(2), because the numeric value 42. is a valid number, JS moves forward on interpreting the full expression. However, it finds toFixed(2), which has no meaningful value (as opposed to the expression .toFixed(2), which represents the execution of a static method.) and throws a syntax error.

Even a space between 42. and toFixed(2) does not solves the problem.

However, a space between 42 and .toFixed(2) solves the problem. Or even a double period 42..toFixed(2) 😮

42.toFixed(2) !== 42..toFixed(2)

Nevertheless, this is how JS interprets the code.

< your WTF >

If you find any WTF that should be here, please let me know 👐

That’s all for Number.

Thanks to 🍻

--

--

Tiago Ferreira
HackerNoon.com

I am helping disrupt the code review process with @reviewpad