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)); # 233
console.log(Math.max.apply(null, list)); # 233
console.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[0],member[1] ... 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 [] -> '3' -> 3console.log(+[3,4]); //Nan console.log(...[3]); //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
Related Topics
Adding Custom Properties to a Function
How to Watch for a Route Change in Angularjs
How to Detect When the Mouse Leaves the Window
Dynamic Function Name in JavaScript
Check If a Value Is Within a Range of Numbers
How to Detect Window.Print() Finish
Onload' Handler for 'Script' Tag in Internet Explorer
Using Jquery to Replace One Tag with Another
Idiomatically Find the Number of Occurrences a Given Value Has in an Array
How to Add a Tooltip to an Svg Graphic
Is There a JSON Equivalent of Xquery/Xpath
Set a Cookie to Httponly via JavaScript
Manipulating Innerhtml Removes the Event Handler of a Child Element
Addition Is Not Working in JavaScript