just when I thought I understood something about type conversion in JavaScript, I stumbled with this:
+[]; // 0
Number([]); // 0
My first thought was that I should get NaN, just like if I try to convert an empty object to number:
+{}; // NaN
Number({}); // NaN
I have been searching about this for a while without any success…
Can somebody explain me why it gets converted to 0 and not to NaN?
Is this behavior standard?
Thanks.
In a brief, there are two key points:
toStringmethod of an empty array returns an empty string.Numberconstructor called as a function (e.g.+"" === 0;).For example, we can use an object that defines a
toStringmethod, and returns an empty string to have an equivalent result:This behavior is completely standard.
Now the long answer:
Both, the unary plus operator and the
Numberconstructor called as a function internally use theToNumberabstract operation.ToNumberwill use two more internal operations,ToPrimitiveand[[DefaultValue]].When the
ToNumberoperation is applied to an Object, such the empty array in your example, it calls theToPrimitiveoperation, to get a representative primitive value and callToNumberagain using that value [1].The
ToPrimitiveoperation receive two arguments, a Value (which is your array object), and a hint type, which in this case is "Number" since we want to make numeric conversion.ToPrimitivecalls the[[DefaultValue]]internal method, also with a "Number" hint type.Now, since the hint type we are using "Number", the
[[DefaultValue]]internal method now will try to invoke first thevalueOfmethod on the object.Array objects don’t have a specific
valueOfmethod, the method is the one inherited fromObject.prototype.valueOf, and this method simply returns a reference to the object itself.Since the
valueOfmethod didn’t result in a primitive value, now thetoStringmethod is invoked, and it produces an empty string (which is a primitive value), then theToNumberoperation will try to do String-Number conversion and it finally end up with0[1].But now you might wonder, why an empty string coerces to zero?
There is a complete grammar that is used when the
ToNumberinternal operation is applied to a String type, theStringNumericLiteralproduction.It has some differences between a NumericLiteral, and one of those differences is that: