Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

javascript

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

like image 286
jtpeterson Avatar asked Jan 11 '17 21:01

jtpeterson


People also ask

What does math min return if equal?

min() The static function Math. min() returns the lowest-valued number passed into it, or NaN if any parameter isn't a number and can't be converted into one.

Why is math MAX () less than math MIN ()?

max() starts with a search value of -Infinity , because any other number is going to be greater than -Infinity. Similarly, Math. min() starts with the search value of Infinity : “If no arguments are given, the result is Infinity .

What is the difference between math MIN () and math MAX () functions?

when you execute Math. min(), you will get (Infinity) and when you execute Math. max(), you will get (-Infinity). by this result for sure if you compare Math.

How does math min work in JS?

The min() function returns the smallest value from the numbers provided. If no parameters are provided, the min() function will return Infinity. If any of the parameters provided are not numbers, the min() function will return NaN.


2 Answers

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.

like image 50
zzzzBov Avatar answered Sep 23 '22 21:09

zzzzBov


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.
like image 31
James Monger Avatar answered Sep 22 '22 21:09

James Monger