Ich weiß, dass JavaScript-Funktionen "beliebig" viele Argumente akzeptieren können.
function f(){};
f(1,2,3,4 /*...*/);
Aber ich frage mich, ob es tatsächlich eine Grenze gibt, wie viele "irgendwelche" sein können?
Nehmen wir zum Beispiel an, ich übergebe eine Million Argumente f()
. Funktioniert das? Oder würde der Dolmetscher umkippen?
Ich vermute, das Maximum ist entweder (a) implementierungsspezifisch oder (b) (2^32)-1
, da das arguments
Objekt Array-ähnlich ist.
Ich sehe dies nicht in der Sprachspezifikation erwähnt, aber ich kann einige Punkte nicht verbinden.
javascript
GladstoneKeep
quelle
quelle
Function.prototype.apply
. stackoverflow.com/questions/1379553/…Math.max
oderArray.prototype.concat(...arrayOfArrays)
(um ein Array von Arrays zu reduzieren) dynamisch an diese Grenze gelangen, ohne eine Monsterfunktion geschrieben zu haben. Der von jfriend00 erwähnte Overhead spielt nicht immer eine Rolle - die Klarheit des Codes ist wichtiger als ein paar Bytes Speicher oder CPU-Zyklen, und die Spread-Syntax ist in dieser Hinsicht manchmal die beste Wahl. Schauen Sie sich Alternativen für "Array reduzieren" zu meinem Funktionscode an ...Antworten:
Obwohl es nichts Spezifisches gibt, das die theoretische maximale Anzahl von Argumenten in der Spezifikation einschränkt (wie die Antwort von thefortheye hervorhebt ). Es gibt natürlich praktische Grenzen. Diese Grenzwerte sind vollständig implementierungsabhängig und hängen höchstwahrscheinlich auch genau davon ab, wie Sie die Funktion aufrufen.
Ich habe diese Geige als Experiment erstellt.
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)); }
Hier sind meine Ergebnisse:
Chrome 33.0.1750.154 m: Der letzte erfolgreiche Test bestand aus 65535 Argumenten. Danach schlug es fehl mit:
Firefox 27.0.1: Der letzte erfolgreiche Test bestand aus 262143 Argumenten. Danach schlug es fehl mit:
Internet Explorer 11: Der letzte erfolgreiche Test bestand aus 131071 Argumenten. Danach schlug es fehl mit:
Opera 12.17: Der letzte erfolgreiche Test bestand aus 1048576 Argumenten. Danach schlug es fehl mit:
Natürlich können hier andere Faktoren eine Rolle spielen und Sie können unterschiedliche Ergebnisse erzielen.
Und hier ist eine alternative Geige, die mit erstellt wurde
eval
. Auch hier können unterschiedliche Ergebnisse erzielt werden.Chrome 33.0.1750.154 m: Der letzte erfolgreiche Test bestand aus 32767 Argumenten. Danach schlug es fehl mit:
Dieser ist besonders interessant, da Chrome selbst verwirrt darüber zu sein scheint, wie viele Argumente tatsächlich zulässig sind.
Firefox 27.0.1: Der letzte erfolgreiche Test bestand aus 32767 Argumenten. Danach schlug es fehl mit:
Internet Explorer 11: Der letzte erfolgreiche Test bestand aus 32767 Argumenten. Danach schlug es fehl mit:
Opera 12.17: Der letzte erfolgreiche Test bestand aus 4194303 Argumenten. Danach schlug es fehl mit:
quelle
apply
Argumente als verwenden und sendenArray
, beträgt das theoretische Maximum pro Spezifikation 4.294.967.295 Elemente, unabhängig von den praktischen Grenzen (?)..apply()
mehr als Funktionsargumenten getestet, die wie in der Frage gezeigt übergeben wurden. Sie sind nicht unbedingt gleich. Hier ist eine Demo, in der ich mit demFunction
Konstruktor eine Funktion aus einer Zeichenfolge erstellt habe . Die Funktion ruft IhretestArgs()
Funktion auf und übergibt ihr 100.000 Argumente. Das bloße Erstellen dieser Funktion schlägt mitSyntaxError: too many function arguments
.apply()
scheint dies wahrscheinlicher. Aber dann hat er es nicht erwähnt.apply()
, also hat er vielleicht vor, etwas zu tuneval
.ECMAScript 5.1, Teil 8.8
Der Standard kennt also keine Grenzen. Wenn Ihr Code in der realen Welt und nicht im Standardland ausgeführt wird, gibt es natürlich eine gewisse Grenze (z. B. Anzahl der Partikel im Universum).
Es gibt zwei Möglichkeiten, Parameter an eine Funktion zu übergeben.
f(a, b, c)
f.apply(null, [a, b, c])
Dieser letztere Weg ist das realistischere Szenario für große Argumentlisten.
Gehen Sie zu dieser JSFiddle , um die jeweiligen Grenzwerte für Ihren aktuellen Browser anzuzeigen .
Ich habe selbst ein paar Browser ausprobiert:
| apply() | literal ---------------------------- Chrome 14 | 131155 | 32767 Chrome 35 | 126213 | 65535 Firefox 30 | 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
Ich habe Unterschiede in vielen dieser Zahlen auf verschiedenen Computern gesehen, daher glaube ich, dass neben dem Browser (dem Betriebssystem?) Andere Faktoren eine Rolle spielen.
Dies ist ein echtes Problem, keine Trivia. Ein Beispiel aus der Praxis:
Die Google Closure Library hat die folgende Funktion definiert.
goog.crypt.byteArrayToString = function(array) { return String.fromCharCode.apply(null, array); };
Dies funktionierte nur, wenn die Länge der Zeichenfolge innerhalb des Browserlimits für die Anzahl der Argumente lag, mit denen übergeben werden kann
Function.prototype.apply
.Die Funktion wurde später gepatcht , was die Funktion erheblich komplizierter machte.
Zu Ihrer Information, im März 2012 wurde ein offenes Webkit-Problem eingereicht, in dem die Argumentationsgrenze erörtert wird.
quelle
Gemäß ECMA Script 5.1 Standardspezifikation für
List
,Der Standard hat also keine Einschränkungen hinsichtlich der Anzahl der Argumente und ist nur durch den Speicher begrenzt.
quelle
> von Computer-Dummheiten
Für mich ist das Limit "groß genug"!
quelle
Es hängt nur davon ab, wie mächtig der Client ist.
Weil der Browser seinen Speicher verliert, wenn Sie Millionen von Argumenten übergeben.
Jede Variable enthält etwas Speicher. Browser haben also kein Problem damit, jeder Variablen Speicher zuzuweisen, bis sie selbst keinen Speicher mehr hat, auf dem sie ausgeführt werden kann.
quelle
Verwenden Sie einfach eine Karte (nur ein Objekt) als einzelnen Parameter. Sie können weiterhin Parameternamen verwenden und können so viele Argumente haben, wie Sie möchten. Es garantiert Ihnen eine theoretisch unendliche Anzahl von Argumenten, die Sie übergeben können, aber Sie bleiben offensichtlich immer noch vom Heap-Speicherplatz begrenzt.
let infiniteParameters = (w) => console.table(w); infiniteParameters({ name1 : "value1", name2 : "value2", // ... });
quelle
Hier ist, wie ich es überprüfe.
let args = []; while(true){ try{ (() => {})(...args); args.push(0); }catch(e){ console.log(e.message); console.log(`Number of arguments: ${args.length}`); break; } }
quelle
Laut dem JavaScript-Funktionsabschnitt von MDN kann eine Funktion maximal 255 Parameter akzeptieren .
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Defining_functions
param The name of an argument to be passed to the function. A function can have up to 255 arguments.
quelle