¿Existe una cantidad máxima de argumentos que las funciones de JavaScript pueden aceptar?

Resuelto GladstoneKeep asked hace 10 años • 8 respuestas

Sé que las funciones de JavaScript pueden aceptar "cualquier" número de argumentos.

function f(){};
f(1,2,3,4 /*...*/);

Pero me pregunto si realmente hay un límite en cuanto a cuántos "cualquiera" pueden ser.

Por ejemplo, digamos que le entrego un millón de argumentos f(). Funcionaría eso? ¿O el intérprete se desmayaría?

Supongo que el máximo es (a) específico de la implementación o (b) (2^32)-1, ya que el argumentsobjeto es similar a una matriz.

No veo que esto se mencione en la especificación del idioma, pero es posible que no esté conectando algunos puntos.

GladstoneKeep avatar Mar 31 '14 00:03 GladstoneKeep
Aceptado

Aunque no hay nada específico que limite el número máximo teórico de argumentos en la especificación (como señala la respuesta de thefortheye ). Por supuesto, existen límites prácticos . Estos límites dependen completamente de la implementación y, muy probablemente, también dependerán exactamente de cómo se llama a la función.


Creé este violín como un experimento.

function testArgs() {
    console.log(arguments.length);
}

var argLen = 0;
for (var i = 1; i < 32; i++) {
    argLen = (argLen << 1) + 1;
    testArgs.apply(null, new Array(argLen));
}

Aquí están mis resultados:

  • Chrome 33.0.1750.154 m: la última prueba exitosa fue de 65535 argumentos. Después de eso falló con:

    RangeError no detectado: se excedió el tamaño máximo de la pila de llamadas

  • Firefox 27.0.1: la última prueba exitosa fue de 262,143 argumentos. Después de eso falló con:

    RangeError: la matriz de argumentos pasada a Function.prototype.apply es demasiado grande

  • Internet Explorer 11: la última prueba exitosa fue de 131.071 argumentos. Después de eso falló con:

    RangeError: SCRIPT28: Sin espacio en la pila

  • Opera 12.17: la última prueba exitosa fue de 1.048.576 argumentos. Después de eso falló con:

    Error: Function.prototype.apply: argArray es demasiado grande

Por supuesto, puede haber otros factores en juego aquí y es posible que obtenga resultados diferentes.


Y aquí hay un violín alternativo creado usando eval. Nuevamente, es posible que obtenga resultados diferentes.

  • Chrome 33.0.1750.154 m: la última prueba exitosa fue de 32,767 argumentos. Después de eso falló con:

    Error de sintaxis no detectado: demasiados argumentos en la llamada a la función (solo se permiten 32766)

    Este es particularmente interesante porque el propio Chrome parece estar confundido acerca de cuántos argumentos están realmente permitidos.

  • Firefox 27.0.1: la última prueba exitosa fue de 32.767 argumentos. Después de eso falló con:

    guión demasiado grande

  • Internet Explorer 11: la última prueba exitosa fue de 32.767 argumentos. Después de eso falló con:

    RangeError: SCRIPT7: Sin memoria

  • Opera 12.17: la última prueba exitosa fue de 4.194.303 argumentos. Después de eso falló con:

    Sin memoria; guión terminado.

p.s.w.g avatar Mar 30 '2014 17:03 p.s.w.g

ECMAScript 5.1, parte 8.8

El tipo Lista se utiliza para explicar la evaluación de listas de argumentos (ver 11.2.4) en nuevas expresiones, en llamadas a funciones y en otros algoritmos donde se necesita una lista simple de valores... Estas secuencias pueden ser de cualquier longitud.

Entonces no hay límite en el estándar. Por supuesto, si su código se ejecuta en el mundo real, no en el mundo de los estándares, obviamente existe algún límite (por ejemplo, número de partículas en el universo).

Hay dos formas de pasar parámetros a una función.

  • "Literalmente":f(a, b, c)
  • Con aplicar():f.apply(null, [a, b, c])

Esta última forma es el escenario más realista para listas de argumentos grandes.

Vaya a este JSFiddle para ver los límites de cada uno de estos para su navegador actual.

Yo mismo probé algunos navegadores:

            | apply() | literal
 -----------------------------
Chrome 14   | 131155  |  32767
Chrome 35   | 126213  |  65535
Chrome 106  | 125625  |  62803
Firefox 30  | 500001  |  65535
Firefox 106 | 500001  |  65535
IE 9        | 254335  |  65533
IE 10       | 253667  |  65533
IE 11       | 252447  |  65533
Opera 22    | 126063  |  65535
Safari 4    | 524215  | 524205
Safari 7    |  65537  | 522159

Vi diferencias en muchos de estos números en diferentes máquinas, por lo que creo que hay otros factores en juego además del navegador (¿el sistema operativo?).


Este es un problema real, no una trivialidad. Un ejemplo del mundo real:

La biblioteca de cierre de Google definió la siguiente función.

goog.crypt.byteArrayToString = function(array) {
  return String.fromCharCode.apply(null, array);
};

Esto funcionó solo si la longitud de la cadena estaba dentro del límite del navegador para la cantidad de argumentos que se pueden pasar Function.prototype.apply.

Posteriormente, la función fue parcheada , lo que la hizo mucho más complicada.


Para su información, hay un problema abierto de Webkit presentado en marzo de 2012 que analiza el límite de argumentos.

Paul Draper avatar Jul 06 '2014 10:07 Paul Draper