How does the Math.max.apply() work?
How does the Math.max.apply()
work?.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<script>
var list = ["12","23","100","34","56",
"9","233"];
console.log(Math.max.apply(Math,list));
</script>
</body>
</html>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
The above code finds the Max number in the List. Can anyone tell me how does the below code work?. It seems it works if i pass null or Math.
console.log(Math.max.apply(Math,list));
Does all the user-defined/Native functions
have call and apply method which we can use?.
Solution 1:
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.
Solution 2:
On JavaScript ES6 just use the Spread operator:
var list = ["12","23","100","34","56","9","233"];
console.log(Math.max(...list));
// ^^^ Spread operator
Solution 3:
Can anyone tell me how does the below code work?
Math.max.apply(Math,list)
Invokes a Math.max
function with Math
object to be used as a this
reference in the function implementation (body) and list
to be passed as an arguments.
So this eventually equals to
Math.max("12","23","100","34","56", "9","233")
It seems it works if i pass null or Math.
Obviously Math.max
implementation doesn't use instance variable - there is no reason to do so. The native implementation would just iterate over arguments
and find the maximum one.
Does all the user-defined/Native functions have call and apply method which we can use?.
Yes, every single function can be invoked using call
or apply
References:
-
MDN
.apply()
documentation (credits to @RGraham)
Solution 4:
I will start by saying Math.max(...numbers)
and Function.prototype.apply()
should only be used for arrays with relatively few elements. (...) and apply will either fail or return the wrong result if the array is too large
Math.max.apply(null | undefined | Math, numbers)
is the same as Math.max(...numbers)
so I would recommend Math.max(...numbers)
for aesthetic reasons.
const numbers = [5, 6, 2, 3, 7];
const max = Math.max(...numbers);
console.log('max:', max);
// expected output: 7
const min = Math.min(...numbers);
console.log('min:', min);
// expected output: 2
If you need to find the maximum element in a numeric array that is very large: use the Array.reduce()
method.
Array.reduce()
can be used to find the maximum element in a numeric array, by comparing each value:
const numbers = [5, 6, 2, 3, 7];
const getMax = (numbers) => numbers.reduce((a, b) => Math.max(a, b));
const getMin = (numbers) => numbers.reduce((a, b) => Math.min(a, b));
const max = getMax(numbers)
const min = getMin(numbers)
console.log('max:', max)
console.log('min:', min)
Conclusion:
Numeric array that is relatively small: use Math.max(...numbers)
Numeric array that is very large: use the Array.reduce()
method
Solution 5:
Math.max(val1, val2,...)
Math.max(1, 2, 3); // Math.max([value1[, value2[, ...]]])
value1, value2...
are parameters and must be Numbers MDN Math.max
You can't pass array
as Math.max
parameters. To pass an array you have to use apply
.
Apply
The first parameter of apply is this
, the second is array
.
Math methods are equivalent of static in other languages, which means it doesn't need an object instance unlike to array.prototype.slice
so you don't need to pass this
in this case.
Example
var arr = [1, 2, 3];
Math.max(1, 2, 3); // -> 3
Math.max(arr); // -> NaN (Not a Number)
Math.max.apply(null, arr); // Math.max.apply(null, [1, 2, 3]) -> Math.max(1, 2, 3) -> 3
arr.slice(1); // -> returns Array [2, 3]
Array.prototype.slice.call(arr, 1); // Array.prototype.slice.call([1, 2, 3], 1) == [1, 2, 3].slice(1)
When you want to pass an array as parameter you have to use apply
, otherwise use call
.
apply = array
call = comma separated
More about call & apply