Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

Why does Math.min([]) evaluate to 0?

I would expect that it would evaluate to NaN since MDN's manpage for Math.min states "If at least one of the arguments cannot be converted to a number, NaN is returned."

So I guess the refined question is why does [] coerce to 0? Especially considering that [] is truthy (i.e. !![] === true) and Math.min(true) === 1. I am thinking about this wrong?

Tested on Node v7.0.0

share|improve this question
2  
an empty array can be converted to a number tho.... the number being zero.. – I wrestled a bear once. 4 hours ago
1  
...because the spec says so. – zzzzBov 4 hours ago
4  
javascript is weird :D – Roljhon 4 hours ago
4  
I think this is because [].toString() yields "" and the specification says that converting "" to a number yields 0. – Andrew Whitaker 4 hours ago
2  
@jtpeterson How would such a thing be useful? Implicit and unintuitive conversions in JavaScript is a root of all hell. And yes, it will stay forever due to backwards compatibility. – freakish 4 hours ago
up vote 9 down vote accepted

Why does Math.min([]) evaluate to 0?

Because the spec says so:

Math.min casts each parameter to a number using...

ToNumber casts objects to a number using...

ToPrimitive casts objects to primitive values using...

[[Default Value]] internal method converts objects to primitives based on their hint parameter.

The default hint for all objects is string. Which means the array gets converted to a string, which for [] is "".

ToNumber then converts "" to 0, per the documented algorithm

Math.min then takes the only parameter and returns it, per its algorithm.

share|improve this answer
2  
Ahhh... hence why only an array of length 0 or 1 will coerce and something like Math.min([1,42]) will result in NaN – jtpeterson 4 hours ago
1  
That makes so much sense!!! not... – Mehrdad 1 hour ago

This happens because [] is coerced to 0.

You can see this with the following call:

(new Number([])).valueOf(); // 0

Therefore, calling Math.min([]) is the same as calling Math.min(0) which gives 0.


I believe that the reason that new Number([]) treats [] as 0 is because:

  1. The spec for the Number(value) constructor uses a ToNumber function.
  2. The spec for the ToNumber(value) function says to use ToPrimitive for an object type (which an array is).
  3. The primitive value of an array is equal to having the array joined, e.g. [] becomes "", [0] becomes "0" and [0, 1] becomes "0,1".
  4. The number constructor therefore converts [] into "" which is then parsed as 0.

The above behaviour is the reason that an array with one or two numbers inside it can be passed into Math.min(...), but an array of more cannot:

  • Math.min([]) is equal to Math.min("") or Math.min(0)
  • Math.min([1]) is equal to Math.min("1") or Math.min(1)
  • Math.min([1, 2]) is equal to Math.min("1,2") which cannot be converted to a number.
share|improve this answer
3  
The original question acknowledges this: "So I guess the refined question is why does [] coerce to 0". I think the OP wants to know why this coercion occurs. – Andrew Whitaker 4 hours ago
1  
javascript : finding innovative ways to be weird since 1995! – Eric Duminil 4 hours ago
1  
Thanks. Array of length 0 or 1 will coerce to a number. Go figure. Here's a link with a useful table at the bottom with more oddities: w3schools.com/js/js_type_conversion.asp – jtpeterson 4 hours ago
    
@jtpeterson I have updated my answer with some examples from the spec to show why arrays of different lengths are coerced. – James Monger 4 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.