Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why an empty Array type-converts to zero? +[]

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.

like image 706
Rick Avatar asked Jul 22 '10 06:07

Rick


People also ask

Is an empty array equal to 0?

The length property sets or returns the number of elements in an array. By knowing the number of elements in the array, you can tell if it is empty or not. An empty array will have 0 elements inside of it.

Why is empty array not equal to empty array?

Because they are not same object, different object never identical equal, so the result is false .

Why is an empty array truthy?

arrays are objects, objects are truthy. just ask for array. length, if not zero, it will be truthy. when you explicitly convert to Boolean, the array turns into an empty string first, then the empty string turns into false.

What is value of empty array?

An array value can be non-empty, empty (cardinality zero), or null. The individual elements in the array can be null or not null. An empty array, an array value of null, and an array for which all elements are the null value are different from each other. An uninitialized array is a null array.


1 Answers

In a brief, there are two key points:

  • The toString method of an empty array returns an empty string.
  • An empty string coerces to zero using the unary plus operator or the Number constructor called as a function (e.g. +"" === 0;).

For example, we can use an object that defines a toString method, and returns an empty string to have an equivalent result:

var obj = { toString: function () { return "";} };
+obj; //  0
Number(obj); // 0

This behavior is completely standard.

Now the long answer:

Both, the unary plus operator and the Number constructor called as a function internally use the ToNumber abstract operation.

ToNumber will use two more internal operations, ToPrimitive and [[DefaultValue]].

When the ToNumber operation is applied to an Object, such the empty array in your example, it calls the ToPrimitive operation, to get a representative primitive value and call ToNumber again using that value [1].

The ToPrimitive operation 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.

ToPrimitive calls 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 the valueOf method on the object.

Array objects don't have a specific valueOf method, the method is the one inherited from Object.prototype.valueOf, and this method simply returns a reference to the object itself.

Since the valueOf method didn't result in a primitive value, now the toString method is invoked, and it produces an empty string (which is a primitive value), then the ToNumber operation will try to do String-Number conversion and it finally end up with 0 [1].

But now you might wonder, why an empty string coerces to zero?

+""; // 0

There is a complete grammar that is used when the ToNumber internal operation is applied to a String type, the StringNumericLiteral production.

It has some differences between a NumericLiteral, and one of those differences is that:

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

like image 167
Christian C. Salvadó Avatar answered Sep 26 '22 01:09

Christian C. Salvadó