0

The following code

var interval = function (a, b) {
          var i, list = [];
          for (i = a; i <= b; i++) {
            list.push(i);
          }
          return list;
        },
    xs = interval(1, 500000);

Math.max.apply(null, xs);

generates an Uncaught RangeError: Maximum call stack size exceeded. How to overcome?

Note that the interval function is just a quick way to generate test data.

I used the Math.max.apply method because it is described here: Mozilla developer network

This is not an acceptable solution because javascript has a maximum number of arguments allowed for a function call, thanks to Rocket Hazmat for pointing it out, see his answer for more informations.

The underscore.js library uses a simple implementation for the max function, and I believe that the most appropriate solution is to include a simple max implementation in the codebase and use it. See @AnotherDev answer for more details

JackNova
  • 3,911
  • 5
  • 31
  • 49
  • 1
    lol - avoid "stack overflow" by solving your own problems :D – DrCord Jun 12 '15 at 18:13
  • 1
    You could simply compute the max while generating the list, or by iterating through the values. http://stackoverflow.com/questions/22747068/is-there-a-max-number-of-arguments-javascript-functions-can-accept – XCS Jun 12 '15 at 18:16
  • P.S. Don't you know the max value already? You're calling `interval` with 2 numbers. Clearly, `b` (500000) is the biggest. – gen_Eric Jun 12 '15 at 18:17
  • @RocketHazmat, the interval there doesn't matter, it is just a way to demonstrate the concept, building fake data – JackNova Jun 12 '15 at 18:21

2 Answers2

4

The issue here is with the line:

Math.max.apply(null, xs);

You are trying to call Math.max(1, 2, 3, 4, ..., 500000);. JavaScript doesn't like calling a function with 500,000 parameters.

See this answer for more info: https://stackoverflow.com/a/22747272

Community
  • 1
  • 1
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
3

If you want a work around, you can use underscore.js

From the source code, it looks like they just loop through the elements using a for loop

for (var i = 0, length = obj.length; i < length; i++) {
        value = obj[i];
        if (value > result) {
          result = value;
        }
      }

Here is an example in JSFiddle

var interval = function (a, b) {
          var i, list = [];
          for (i = a; i <= b; i++) {
            list.push(i);
          }
          return list;
        },
    xs = interval(1, 500000);

console.log(_.max(xs))
//prints 500000
tcigrand
  • 2,357
  • 2
  • 14
  • 24
  • 1
    Thanks @AnotherDev, I looked in underscore sources too and reached the same conclusion, calling Math.max.apply on a large array is not allowed, the best approach is to have a max() implementation in the codebase – JackNova Jun 12 '15 at 18:31