﻿ How Does the Math.Max.Apply() Work - ITCodar

# How Does the Math.Max.Apply() Work

## How does the Math.max.apply() work?

`apply` accepts an array and it applies the array as parameters to the actual function. So,

``Math.max.apply(Math, list);``

can be understood as,

``Math.max("12", "23", "100", "34", "56", "9", "233");``

So, `apply` is a convenient way to pass an array of data as parameters to a function. Remember

``console.log(Math.max(list));   # NaN``

will not work, because `max` doesn't accept an array as input.

There is another advantage, of using `apply`, you can choose your own context. The first parameter, you pass to `apply` of any function, will be the `this` inside that function. But, `max` doesn't depend on the current context. So, anything would work in-place of `Math`.

``console.log(Math.max.apply(undefined, list));   # 233console.log(Math.max.apply(null, list));        # 233console.log(Math.max.apply(Math, list));        # 233``

Since `apply` is actually defined in `Function.prototype`, any valid JavaScript function object, will have `apply` function, by default.

## use of Javascript math.max.apply(null or math..)

If you use `arr1.push(arr2)`, the result is different:

``['a', 'b', ['c', 'd']]``

To get the same result as your original `arr1.push.apply`, you would have to do

``arr1.concat(arr2);``

`apply` takes the array argument and turns each element into a separate argument to the function being called. When you call the function normally, the array is just a single argument.

The normal way to call `Math.max` is with each number that it's comparing as a separate argument:

``Math.max(-1, 5, 11, 3);``

In order to get the arguments from an array, you have to use `apply` to spread them.

The reason for the `null` argument to in the second case is because the first argument to `apply` is the context of the function, i.e. the value that will be assigned to `this` inside the function. When you call a function normally, the context is the value before the `.`; for example, when you write

``arr1.push('x');``

the context is the `arr1` array. `Math.max()` doesn't use its context, but you have to pass something, so `null` is a common placeholder. But when we call `push` using `apply`, we have to pass `arr1` as the context, so it knows which array to modify. Some people like to write

``Math.max.apply(Math, [-1, 5, 11, 3]);``

so that the context will be the same as if you'd called `Math.max` in the normal way. But it doesn't matter in this case.

## Someone please explain the Function.apply.bind(Math.max, null) algorithm

Looking at the entire expression:

``arr.map(Function.apply.bind(Math.max, null));``

map expects its first argument to be a function, which is returned by:

``Function.apply.bind(Math.max, null);``

Function.apply is a shorter version of Function.prototype.apply.

Calling bind on it returns a special version of apply whose this is set to Math.max and when called, will have as it's first parameter (i.e. the value that would normally be used as this) set to null, since it's not going to be used.

So each element in arr will effectively be called using:

``Math.max.apply(null, member);``

The use of apply means the values in member are passed as parameters, as if:

``Math.max(member,member ... member[n]); ``

So the expression returns the maximum value in each array. Those values are returned to map, which puts them into a new array.

``var arr = [[1,2,3],[4,5,6]];console.log(  arr.map(Function.apply.bind(Math.max, null)) //[3, 6]);``

## How do i use Math.max with an array of objects?

You'll have to extract the properties from the objects yourself:

``var maximum = Math.max.apply(Math, myArr.map(function(o) { return o.x; }));``

That uses `.map()` to iterate through the elements of the array and return the value of the "x" property. That result array is then passed as the arguments to `Math.max()`.

Now that `=>` functions are widely available it'd be a little shorter as so:

``var maximum = Math.max.apply(Math, myArr.map(o => o.x));``

Still doing pretty much the exact same thing of course.

## Why Math.max(...[]) is equal to -Infinity in ES2015?

What happens with `Math.max([])` is that `[]` is first converted to a string and then to a number. It is not actually considered an array of arguments.

With `Math.max(...[])` the array is considered a collection of arguments through the spread operator. Since the array is empty, this is the same as calling without arguments.
Which according to the docs produces -Infinity

If no arguments are given, the result is -Infinity.

Some examples to show the difference in calls with arrays:

``console.log(+[]); //0    [] -> '' -> 0console.log(+); //3    [] -> '3' -> 3console.log(+[3,4]); //Nan console.log(...); //3console.log(...[3,4]); //3 4 (the array is used as arguments)console.log(Math.max([])); //0  [] is converted to 0console.log(Math.max()); // -infinity:  default without argumentsconsole.log(Math.max(...[])); // -infinityconsole.log(Math.max([3,4])); //Nanconsole.log(Math.max(...[3,4])); //4``