Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
418 views
in Technique[技术] by (71.8m points)

javascript - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In a brief, there are two key points:

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...