Ist es möglich, alle Argumente einer Funktion als einzelnes Objekt innerhalb dieser Funktion abzurufen?

Antworten:

346

Verwenden Sie arguments. Sie können wie ein Array darauf zugreifen. Verwenden Sie arguments.lengthfür die Anzahl der Argumente.

Thomas Eding
quelle
46
Dies funktioniert nur für das traditionelle JavaScript function, nicht für ES2015 + Fettpfeilfunktionen =>. Für diese möchten Sie ...argsin der Funktionsdefinition wie folgt verwenden : (...args) => console.log(args).
Sawtaytoes
141

Die Argumente sind ein Array-ähnliches Objekt (kein tatsächliches Array). Beispielfunktion ...

function testArguments () // <-- notice no arguments specified
{
    console.log(arguments); // outputs the arguments to the console
    var htmlOutput = "";
    for (var i=0; i < arguments.length; i++) {
        htmlOutput += '<li>' + arguments[i] + '</li>';
    }
    document.write('<ul>' + htmlOutput + '</ul>');
}

Versuch es...

testArguments("This", "is", "a", "test");  // outputs ["This","is","a","test"]
testArguments(1,2,3,4,5,6,7,8,9);          // outputs [1,2,3,4,5,6,7,8,9]

Die vollständigen Details: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments

Luke
quelle
3
Warum nicht auch hier das Ergebnis posten? :)
Jonathan Azulay
2
Dies ist viel besser als die akzeptierte Antwort, da sie ein funktionierendes Code-Snippet enthält und die Ausgabe anzeigt. Die akzeptierte Antwort ist zu spärlich.
Mac
Gute Antwort ... wäre eine großartige Antwort mit der Erweiterung auf "kein tatsächliches Array"
terpinmd
Ich habe einen Link zu einer einfachen Beschreibung hinzugefügt: Ein "Array-ähnliches Objekt" ist nur ein "Objekt mit einer Längeneigenschaft einer nicht negativen Ganzzahl und normalerweise einigen indizierten Eigenschaften". Aus dem Mozilla-Link: "Es ähnelt einem Array, hat jedoch keine Array-Eigenschaften außer der Länge."
Luke
31

ES6 ermöglicht ein Konstrukt, bei dem ein Funktionsargument mit der Notation "..." angegeben wird, z

function testArgs (...args) {
 // Where you can test picking the first element
 console.log(args[0]); 
}
Gunnar Forsgren - Mobimation
quelle
3
Dies scheint der einzige Weg zu sein, wenn die Pfeilfunktion verwendet wird. a = () => {console.log(arguments);}; a('foo');gibt -- Uncaught ReferenceError: arguments is not defined jedoch a = (...args) => {console.log(args);}; a('foo');gibt["foo"]
David Baucum
1
@ DavidBaucum das ist richtig. Da die Pfeilfunktion keinen neuen Bereich erstellt und "Argumente" aus dem Bereich erfasst werden. Das Worst-Case-Szenario ist jedoch kein ReferenceError. Es ist so, dass "Argumente" aus einem äußeren Bereich gesammelt werden. Dann erhalten Sie keine Ausnahme und möglicherweise seltsame Fehler in Ihrer Anwendung.
Pgsandstrom
1
Dies wird auch als "Ruheparameter" bezeichnet, siehe developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Dennis
21

Im argumentsObjekt werden die Funktionsargumente gespeichert.

Das Argumentobjekt verhält sich und sieht aus wie ein Array. Es verfügt im Grunde genommen nicht über die Methoden, die Arrays ausführen, zum Beispiel:

Array.forEach(callback[, thisArg]);

Array.map(callback[, thisArg])

Array.filter(callback[, thisArg]);

Array.slice(begin[, end])

Array.indexOf(searchElement[, fromIndex])

Ich denke, der beste Weg, ein argumentsObjekt in ein echtes Array zu konvertieren, ist folgender:

argumentsArray = [].slice.apply(arguments);

Das macht es zu einem Array;

wiederverwendbar:

function ArgumentsToArray(args) {
    return [].slice.apply(args);
}

(function() {
   args = ArgumentsToArray(arguments);

   args.forEach(function(value) {
      console.log('value ===', value);
   });

})('name', 1, {}, 'two', 3)

Ergebnis:

> value === name
> value === 1
> value === Object {}
> value === two
>value === 3

iConnor
quelle
1
[].slice.apply(arguments);kann nicht der beste Weg sein, weil es eine unnötige leere Array-Zuordnung verursacht.
Thomas Eding
10

Sie können es auch in ein Array konvertieren, wenn Sie dies bevorzugen. Wenn Array-Generika verfügbar sind:

var args = Array.slice(arguments)

Andernfalls:

var args = Array.prototype.slice.call(arguments);

von Mozilla MDN :

Sie sollten nicht auf Argumente verzichten, da dies Optimierungen in JavaScript-Engines (z. B. V8) verhindert.

Iman Mohamadi
quelle
2
Danke für das Update. Verwenden Sie alternativ JSON.stringify und JSON.parse: function foo() { foo.bar = JSON.stringify(arguments); foo.baz = JSON.parse(foo.bar); } Wenn anstelle der Stringifizierung eine Aufbewahrung erforderlich ist, verwenden Sie den internen strukturierten Klonalgorithmus . Wenn DOM-Knoten übergeben werden, verwenden Sie XMLSerializer wie in einer nicht verwandten Frage . with (new XMLSerializer()) {serializeToString(document.documentElement) }
Paul Sweatte
7

argumentsEnthält, wie viele andere betonten, alle an eine Funktion übergebenen Argumente.

Wenn Sie eine andere Funktion mit denselben Argumenten aufrufen möchten, verwenden Sie apply

Beispiel:

var is_debug = true;
var debug = function() {
  if (is_debug) {
    console.log.apply(console, arguments);
  }
}

debug("message", "another argument")
Lasse Skindstad Ebert
quelle
4

Ähnliche Antwort zu Gunnar mit vollständigerem Beispiel: Sie können das Ganze sogar transparent zurückgeben:

function dumpArguments(...args) {
  for (var i = 0; i < args.length; i++)
    console.log(args[i]);
  return args;
}

dumpArguments("foo", "bar", true, 42, ["yes", "no"], { 'banana': true });

Ausgabe:

foo
bar
true
42
["yes","no"]
{"banana":true}

https://codepen.io/fnocke/pen/mmoxOr?editors=0010

Frank Nocke
quelle
3

Ja, wenn Sie keine Ahnung haben, wie viele Argumente zum Zeitpunkt der Funktionsdeklaration möglich sind, können Sie die Funktion ohne Parameter deklarieren und über das Argumentarray, das zum Zeitpunkt des Funktionsaufrufs übergeben wird, auf alle Variablen zugreifen.

Rubi saini
quelle
2

In ES6 können Sie Folgendes tun:

function foo(...args) 
{
   let [a,b,...c] = args;

   console.log(a,b,c);
}


foo(1, null,"x",true, undefined);

Kamil Kiełczewski
quelle
1
Sie können sogar die Funktion `` `foo (a, b, ... c) {console.log (a, b, c) ausführen; } `` `
TitouanT
-11

Verwenden Sie in ES6 Array.from:

function foo()
  {
  foo.bar = Array.from(arguments);
  foo.baz = foo.bar.join();
  }

foo(1,2,3,4,5,6,7);
foo.bar // Array [1, 2, 3, 4, 5, 6, 7]
foo.baz // "1,2,3,4,5,6,7"

Verwenden Sie für Nicht-ES6-Code JSON.stringify und JSON.parse:

function foo()
  {
  foo.bar = JSON.stringify(arguments); 
  foo.baz = JSON.parse(foo.bar); 
  }

/* Atomic Data */
foo(1,2,3,4,5,6,7);
foo.bar // "{"0":1,"1":2,"2":3,"3":4,"4":5,"5":6,"6":7}"
foo.baz // [object Object]

/* Structured Data */
foo({1:2},[3,4],/5,6/,Date())
foo.bar //"{"0":{"1":2},"1":[3,4],"2":{},"3":"Tue Dec 17 2013 16:25:44 GMT-0800 (Pacific Standard Time)"}"
foo.baz // [object Object]

Wenn anstelle einer Stringifizierung eine Aufbewahrung erforderlich ist, verwenden Sie den internen strukturierten Klonierungsalgorithmus .

Wenn DOM-Knoten übergeben werden, verwenden Sie XMLSerializer wie in einer nicht verwandten Frage .

with (new XMLSerializer()) {serializeToString(document.documentElement) }

Wenn Sie als Lesezeichen ausgeführt werden, müssen Sie möglicherweise jedes Argument für strukturierte Daten in einen Fehlerkonstruktor einschließen, damit JSON.stringifyes ordnungsgemäß funktioniert.

Verweise

Paul Sweatte
quelle
3
Erstens: Dadurch werden alle übergebenen Objekte geklont. Zweitens: Nicht alles kann mit JSON verknüpft werden. Nämlich: Funktionen, DOM-Objekte, besagte Daten werden als Zeichenfolgen stringifiziert ...
John Dvorak
@JanDvorak Können Sie meine Antwort mit einer Funktion bearbeiten, die DOM-Objekte, -Funktionen und -Daten verarbeitet?
Paul Sweatte
1
+1 Wenn Sie versuchen, die Argumente für die Fehlerberichterstattung als Zeichenfolge zu übergeben, wird das Objekt als Zeichenfolge '[Objektargumente]' angezeigt. Wenn Sie dies an der Konsole protokollieren, werden die Werte nicht angezeigt. Obwohl es das OP nicht zu beantworten scheint, beantwortet es meine Frage, danke!
John