JS WTF 🦄 with Number
Time to ride on some JavaScript WTF with Number.
‘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 🍻
- MDN Documentation
- Kyle Simpson for his video and book
- All the kitties in the world
- Hacker Noon for publishing ❤️
Be sure to check out my other articles on JS WTF