0

if Math.max([1,3,9]) returns error (needs a list of numbers, not an array), why calling it via apply like below works?

function getMaxOfArray(numArray) {
 return Math.max.apply(null, numArray);
}

getMaxOfArray([1,3,9]) //9 
getMaxOfArray(1,3,9) //error

I understand .apply passes an array, but why should max function work with them only when called via apply? is there some internal transformation array => list ?

user1249791
  • 1,169
  • 4
  • 13
  • 27

3 Answers3

3

apply expects the parameters to be in an array. if you just have the parameter list how you do in the second case, use call instead

Math.max.apply(null,[1,3,9])
Math.max.call(null,1,3,9)

What is the difference between call and apply? goes into a good amount of detail on the difference between call and apply

Community
  • 1
  • 1
Jeff Storey
  • 53,386
  • 69
  • 224
  • 390
  • I know the difference between .apply and .call, what I cannot understand is why if we use Math.max([1,3,9]) returns error (we are passing an array) but using... Math.max.apply(null, numArray) works (we are also passing an array to Math.max) – user1249791 Jul 21 '13 at 21:53
  • Because the `Math.max` function does not take an array https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max. `apply` does (always) take an array. `apply` unwraps the arguments in the array, so a call to `Math.max.apply(null,[1,3,9])` is the same as `Math.max(1,3,9)` not `Math.max([1,3,9])` – Jeff Storey Jul 21 '13 at 23:13
  • so, if we want to pass an array to a function via .apply we have to reconstruct this array? if i am not wrong, func.apply(thisValue, [arg1, arg2, ...]) is equivalent to func(arg1,arg2,arg3), so if func needs an array will fail... – user1249791 Jul 22 '13 at 08:32
  • If the function needs an array, you could do `func.apply(null,[a,b,[c,d]])` would be equivalent to `func(a,b,[c,d])`. – Jeff Storey Jul 22 '13 at 14:42
2

Your function only accepts one argument (numArray), not three—this is why your call to getMaxOfArray is failing. If you are writing a one-liner, you should use call instead of apply for a series of parameters rather than an array, as so:

Math.max.apply(null, [1, 3, 9]);
Math.max.call(null, 1, 3, 9);

For a function, you can use the arguments object for a variable number of parameters, if you do not want the user to pass an array. Here's how you would go about doing it this way. (Note that I still call apply here, because I store all of the arguments called by the user into an array.)

function getMaxOfArguments() {
   var parameters = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
   return Math.max.apply(null, parameters);
}

Now, your second function call should work:

getMaxOfArguments(1, 3, 9); // 9
kevinji
  • 9,983
  • 4
  • 35
  • 55
  • I know the difference between .apply and .call, what I cannot understand is why if we use Math.max([1,3,9]) returns error (we are passing an array) but using... Math.max.apply(null, numArray) works (we are also passing an array to Math.max) – user1249791 Jul 21 '13 at 21:50
0

The function signature of Math.max is function(arg1, arg2, arg3, ...) not function(Array). Apply is converting the input into a more palatable form for Math.max.

CharlesTWall3
  • 540
  • 3
  • 12
  • I also understand there is some transformation array -> list of parameters in that case when using .apply(), otherwise Math.Max should return error when passing the array. What I am curious is in which cases this happens?? allways? why only when calling the function via .apply and not the 'normal' way? – user1249791 Jul 21 '13 at 21:56