it-swarm.com.de

JavaScript-Variable Anzahl der zu funktionierenden Argumente

Gibt es eine Möglichkeit, "unbegrenzte" Variablen für eine Funktion in JavaScript zuzulassen?

Beispiel:

load(var1, var2, var3, var4, var5, etc...)
load(var1)
493
Timo

Verwenden Sie einfach das Objekt arguments.

function foo() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}
771
roufamatic

In (den meisten) neueren Browsern können Sie eine variable Anzahl von Argumenten mit dieser Syntax akzeptieren:

function my_log(...args) {
     // args is an Array
     console.log(args);
     // You can pass this array as parameters to another function
     console.log(...args);
}

Hier ist ein kleines Beispiel:

function foo(x, ...args) {
  console.log(x, args, ...args, arguments);
}

foo('a', 'b', 'c', z='d')

=>

a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
​    0: "a"
    ​1: "b"
    ​2: "c"
    ​3: "d"
    ​length: 4

Dokumentation und weitere Beispiele hier: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters

136
Ramast

Eine andere Möglichkeit besteht darin, Ihre Argumente in einem Kontextobjekt zu übergeben.

function load(context)
{
    // do whatever with context.name, context.address, etc
}

und benutze es so

load({name:'Ken',address:'secret',unused:true})

Dies hat den Vorteil, dass Sie so viele benannte Argumente hinzufügen können, wie Sie möchten, und die Funktion diese verwenden kann (oder nicht), wie sie es für richtig hält.

109
Ken

Ich stimme Kens Antwort als die dynamischste zu und gehe gerne noch einen Schritt weiter. Wenn es sich um eine Funktion handelt, die Sie mehrmals mit unterschiedlichen Argumenten aufrufen, verwende ich Kens Design, füge dann aber Standardwerte hinzu:

function load(context) {

    var defaults = {
        parameter1: defaultValue1,
        parameter2: defaultValue2,
        ...
    };

    var context = extend(defaults, context);

    // do stuff
}

Auf diese Weise können Sie, wenn Sie viele Parameter haben, diese aber nicht bei jedem Aufruf der Funktion festlegen müssen, einfach die Nicht-Standardeinstellungen festlegen. Für die extend-Methode können Sie die extend-Methode von jQuery ($.extend()) verwenden, Ihre eigene erstellen oder Folgendes verwenden:

function extend() {
    for (var i = 1; i < arguments.length; i++)
        for (var key in arguments[i])
            if (arguments[i].hasOwnProperty(key))
                arguments[0][key] = arguments[i][key];
    return arguments[0];
}

Dadurch wird das Kontextobjekt mit den Standardwerten zusammengeführt, und undefinierte Werte in Ihrem Objekt werden mit den Standardwerten gefüllt.

45
mbeasley

Ja, einfach so:

function load()
{
  var var0 = arguments[0];
  var var1 = arguments[1];
}

load(1,2);
18
Canavar

Es ist vorzuziehen, die rest-Parametersyntax zu verwenden, wie Ramast betont hat.

function (a, b, ...args) {}

Ich möchte nur eine nette Eigenschaft des Arguments ... args hinzufügen

  1. Es ist ein Array und kein Objekt wie Argumente. Auf diese Weise können Sie Funktionen wie Map oder Sort direkt anwenden.
  2. Es enthält nicht alle Parameter, sondern nur den weitergegebenen. Z.B. Funktion (a, b, ... args) In diesem Fall enthält args das Argument 3 bis arguments.length
14
Nicola Pedretti

Wie bereits erwähnt, können Sie mit dem Objekt arguments eine variable Anzahl von Funktionsparametern abrufen.

Wenn Sie eine andere Funktion mit denselben Argumenten aufrufen möchten, verwenden Sie apply. Sie können sogar Argumente hinzufügen oder entfernen, indem Sie arguments in ein Array konvertieren. Diese Funktion fügt beispielsweise Text ein, bevor Sie sich an der Konsole anmelden:

log() {
    let args = Array.prototype.slice.call(arguments);
    args = ['MyObjectName', this.id_].concat(args);
    console.log.apply(console, args);
}
13
Peter Tseng

Obwohl ich im Allgemeinen zustimme, dass der Ansatz mit den genannten Argumenten nützlich und flexibel ist (es sei denn, Sie interessieren sich für die Reihenfolge, in welchem ​​Fall Argumente am einfachsten sind), habe ich Bedenken hinsichtlich der Kosten des mbeasley-Ansatzes (unter Verwendung von Standardwerten und Erweiterungen). Dies ist ein extremer Kostenaufwand für das Abrufen von Standardwerten. Zunächst werden die Standardeinstellungen in der Funktion definiert, sodass sie bei jedem Aufruf neu aufgefüllt werden. Zweitens können Sie auf einfache Weise die benannten Werte auslesen und gleichzeitig die Standardwerte mit || festlegen. Es ist nicht erforderlich, ein weiteres neues Objekt zu erstellen und zusammenzuführen, um diese Informationen abzurufen.

function load(context) {
   var parameter1 = context.parameter1 || defaultValue1,
       parameter2 = context.parameter2 || defaultValue2;

   // do stuff
}

Dies ist ungefähr die gleiche Menge an Code (möglicherweise etwas mehr), sollte jedoch einen Bruchteil der Laufzeitkosten ausmachen.

8
mcurland

Während @roufamatic die Verwendung des Schlüsselworts arguments gezeigt hat und @Ken ein großartiges Beispiel für ein Verwendungsobjekt gezeigt hat, bin ich der Meinung, dass weder wirklich angesprochen wird, was in diesem Fall vor sich geht, noch dass zukünftige Leser verwirrt werden oder dass eine schlechte Praxis darin besteht, keine Funktion explizit anzugeben Die Methode/soll eine variable Anzahl von Argumenten/Parametern annehmen.

function varyArg () {
    return arguments[0] + arguments[1];
}

Wenn ein anderer Entwickler Ihren Code durchsucht, ist es sehr einfach anzunehmen, dass diese Funktion keine Parameter akzeptiert. Insbesondere, wenn dieser Entwickler nicht mit dem Schlüsselwort arguments vertraut ist. Aus diesem Grund ist es eine gute Idee, einer Stilrichtlinie zu folgen und konsequent zu sein. Ich werde Google für alle Beispiele verwenden.

Stellen wir explizit fest, dass dieselbe Funktion variable Parameter hat:

function varyArg (var_args) {
    return arguments[0] + arguments[1];
}

Objektparameter VS var_args

Es kann vorkommen, dass ein Objekt benötigt wird, da es die einzige genehmigte und als bewährte Methode für eine Datenzuordnung darstellt. Assoziative Arrays werden verpönt und entmutigt.

SIDENOTE: Das Schlüsselwort arguments gibt tatsächlich ein Objekt mit Zahlen als Schlüssel zurück. Die prototypische Vererbung ist auch die Objektfamilie. Informationen zur ordnungsgemäßen Verwendung von Arrays in JS finden Sie am Ende der Antwort

In diesem Fall können wir dies auch ausdrücklich angeben. Hinweis: Diese Namenskonvention wird nicht von Google bereitgestellt, ist jedoch ein Beispiel für die explizite Deklaration eines Param-Typs. Dies ist wichtig, wenn Sie ein strengeres typisiertes Muster in Ihrem Code erstellen möchten.

function varyArg (args_obj) {
    return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});

Welches soll ich wählen?

Dies hängt von den Anforderungen Ihrer Funktion und Ihres Programms ab. Wenn Sie zum Beispiel einfach nach einer Wertebasis für einen iterativen Prozess über alle übergebenen Argumente suchen, bleiben Sie mit Sicherheit beim Schlüsselwort arguments. Wenn Sie eine Definition Ihrer Argumente und eine Zuordnung der Daten benötigen, ist die Objektmethode der richtige Weg. Schauen wir uns zwei Beispiele an und dann sind wir fertig!

Verwendung der Argumente

function sumOfAll (var_args) {
    return arguments.reduce(function(a, b) {
        return a + b;
    }, 0);
}
sumOfAll(1,2,3); // returns 6

Objektnutzung

function myObjArgs(args_obj) {
    // MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
    if (typeof args_obj !== "object") {
        return "Arguments passed must be in object form!";
    }

    return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old

Zugriff auf ein Array anstelle eines Objekts ("... args" Der rest-Parameter)

Wie oben in der Antwort erwähnt, gibt das Schlüsselwort arguments tatsächlich ein Objekt zurück. Aus diesem Grund muss jede Methode, die Sie für ein Array verwenden möchten, aufgerufen werden. Ein Beispiel dafür:

Array.prototype.map.call(arguments, function (val, idx, arr) {});

Um dies zu vermeiden, verwenden Sie den Parameter rest:

function varyArgArr (...var_args) {
    return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5
6
Brian Ellis

Verwenden Sie das Objekt arguments innerhalb der Funktion, um Zugriff auf alle übergebenen Argumente zu erhalten.

5
nickytonline

Beachten Sie, dass das Übergeben eines Objekts mit benannten Eigenschaften, wie von Ken vorgeschlagen, die Kosten für das Zuweisen und Freigeben des temporären Objekts bei jedem Aufruf erhöht. Die Übergabe von normalen Argumenten als Wert oder Referenz ist im Allgemeinen am effizientesten. Für viele Anwendungen ist die Leistung zwar nicht kritisch, für einige kann es jedoch sein.

3
phbcanada