Wenn ich eine JavaScript-Funktion mit mehreren Argumenten erstelle, bin ich immer mit dieser Auswahl konfrontiert: Übergeben einer Liste von Argumenten vs. Übergeben eines Optionsobjekts.
Zum Beispiel schreibe ich eine Funktion, um eine Knotenliste einem Array zuzuordnen:
function map(nodeList, callback, thisObject, fromIndex, toIndex){
...
}
Ich könnte stattdessen folgendes verwenden:
function map(options){
...
}
Dabei ist Optionen ein Objekt:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
Welcher ist der empfohlene Weg? Gibt es Richtlinien, wann einer gegen den anderen verwendet werden soll?
[Update] Es scheint einen Konsens zugunsten des Optionsobjekts zu geben, daher möchte ich einen Kommentar hinzufügen: Ein Grund, warum ich versucht war, die Liste der Argumente in meinem Fall zu verwenden, war ein Verhalten, das mit dem JavaScript übereinstimmt eingebaute array.map Methode.
Array.prototype.map
hat eine einfache API, die keinen halb erfahrenen Programmierer verwirren sollte.Antworten:
Wie viele andere ziehe ich es oft vor, ein
options object
an eine Funktion zu übergeben, anstatt eine lange Liste von Parametern zu übergeben, aber es hängt wirklich vom genauen Kontext ab.Ich benutze die Lesbarkeit von Code als Lackmustest.
Zum Beispiel, wenn ich diesen Funktionsaufruf habe:
Ich denke, dass Code so wie er ist gut lesbar ist und das Übergeben einzelner Parameter in Ordnung ist.
Auf der anderen Seite gibt es Funktionen mit Aufrufen wie diesen:
Völlig unlesbar, es sei denn, Sie recherchieren. Auf der anderen Seite liest sich dieser Code gut:
Es ist eher eine Kunst als eine Wissenschaft, aber wenn ich Faustregeln nennen müsste:
Verwenden Sie einen Optionsparameter, wenn:
quelle
Mehrere Argumente beziehen sich meist auf obligatorische Parameter. Es ist nichts falsch mit ihnen.
Wenn Sie optionale Parameter haben, wird es kompliziert. Wenn sich einer von ihnen auf die anderen verlässt, so dass sie eine bestimmte Reihenfolge haben (z. B. benötigt der vierte die dritte), sollten Sie dennoch mehrere Argumente verwenden. Fast alle nativen EcmaScript- und DOM-Methoden funktionieren so. Ein gutes Beispiel ist die
open
Methode von XMLHTTPrequests , bei der die letzten drei Argumente optional sind. Die Regel lautet "kein Kennwort ohne Benutzer" (siehe auch MDN-Dokumente ).Optionsobjekte sind in zwei Fällen nützlich:
undefined
.In Ihrem Fall würde ich empfehlen
map(nodeList, callback, options)
.nodelist
undcallback
erforderlich sind, kommen die anderen drei Argumente nur gelegentlich und haben vernünftige Standardeinstellungen.Ein anderes Beispiel ist
JSON.stringify
. Möglicherweise möchten Sie denspace
Parameter verwenden, ohne einereplacer
Funktion zu übergeben - dann müssen Sie aufrufen…, null, 4)
. Ein Argumentobjekt wäre möglicherweise besser gewesen, obwohl es für nur zwei Parameter nicht wirklich sinnvoll ist.quelle
Die Verwendung des Ansatzes "Optionen als Objekt" ist am besten. Sie müssen sich keine Gedanken über die Reihenfolge der Eigenschaften machen und es gibt mehr Flexibilität bei der Datenübergabe (z. B. optionale Parameter).
Das Erstellen eines Objekts bedeutet auch, dass die Optionen problemlos für mehrere Funktionen verwendet werden können:
quelle
Ich denke, wenn Sie etwas instanziieren oder eine Methode eines Objekts aufrufen, möchten Sie ein Optionsobjekt verwenden. Wenn es sich um eine Funktion handelt, die nur einen oder zwei Parameter verarbeitet und einen Wert zurückgibt, ist eine Argumentliste vorzuziehen.
In einigen Fällen ist es gut, beide zu verwenden. Wenn Ihre Funktion einen oder zwei erforderliche Parameter und eine Reihe optionaler Parameter hat, machen Sie die ersten beiden erforderlichen Parameter und den dritten zu einem optionalen Options-Hash.
In Ihrem Beispiel würde ich tun
map(nodeList, callback, options)
. Knotenliste und Rückruf sind erforderlich. Es ist ziemlich einfach zu erkennen, was gerade passiert, indem Sie einen Anruf lesen, und es ist wie bei vorhandenen Kartenfunktionen. Alle anderen Optionen können als optionaler dritter Parameter übergeben werden.quelle
Ihr Kommentar zur Frage:
Warum also nicht? (Hinweis: Dies ist ziemlich rohes Javascript. Normalerweise würde ich einen
default
Hash verwenden und ihn mit den Optionen aktualisieren, die mit Object.extend oder JQuery.extend oder ähnlichem übergeben wurden.)Da es jetzt viel offensichtlicher ist, was optional ist und was nicht, sind all dies gültige Verwendungen der Funktion:
quelle
Ich bin mit dieser Antwort vielleicht etwas spät dran, aber ich habe nach Meinungen anderer Entwickler zu diesem Thema gesucht und bin auf diesen Thread gestoßen.
Ich bin mit den meisten Antwortenden nicht einverstanden und stehe dem Ansatz der „Mehrfachargumente“ gegenüber. Mein Hauptargument ist, dass es andere Anti-Muster wie "Mutieren und Zurückgeben des Parameterobjekts" oder "Weitergeben des gleichen Parameterobjekts an andere Funktionen" entmutigt. Ich habe in Codebasen gearbeitet, die dieses Anti-Pattern ausgiebig missbraucht haben, und das Debuggen von Code, der dies tut, wird schnell unmöglich. Ich denke, dies ist eine sehr Javascript-spezifische Faustregel, da Javascript nicht stark typisiert ist und solche willkürlich strukturierten Objekte zulässt.
Meine persönliche Meinung ist, dass Entwickler beim Aufrufen von Funktionen explizit sein sollten, redundante Daten nicht weitergeben und Änderungen durch Verweise vermeiden sollten. Es ist nicht so, dass dieses Muster das Schreiben von präzisem, korrektem Code ausschließt. Ich habe nur das Gefühl, dass es für Ihr Projekt viel einfacher ist, in schlechte Entwicklungspraktiken zu verfallen.
Betrachten Sie den folgenden schrecklichen Code:
Diese Art erfordert nicht nur eine explizitere Dokumentation, um die Absicht zu spezifizieren, sondern lässt auch Raum für vage Fehler. Was passiert , wenn ein Entwickler ändert
param1
inbar()
? Wie lange würde es Ihrer Meinung nach dauern, eine Codebasis von ausreichender Größe zu durchsuchen, um dies zu erfassen? Zugegeben, dieses Beispiel ist etwas unaufrichtig, da davon ausgegangen wird, dass Entwickler zu diesem Zeitpunkt bereits mehrere Anti-Patterns begangen haben. Es zeigt jedoch, wie das Übergeben von Objekten, die Parameter enthalten, mehr Raum für Fehler und Mehrdeutigkeiten bietet und ein höheres Maß an Gewissenhaftigkeit und die Einhaltung der Konstantenkorrektheit erfordert.Nur meine zwei Cent zu diesem Thema!
quelle
Es hängt davon ab, ob.
Basierend auf meiner Beobachtung zum Design dieser gängigen Bibliotheken sind hier die Szenarien, die wir als Optionsobjekt verwenden sollten:
Und Szenarien zur Verwendung der Parameterliste:
quelle
Objekt ist vorzuziehen, da es beim Übergeben eines Objekts einfach ist, die Anzahl der Eigenschaften in diesen Objekten zu erweitern, und Sie nicht auf die Reihenfolge achten müssen, in der Ihre Argumente übergeben wurden.
quelle
Für eine Funktion, die normalerweise einige vordefinierte Argumente verwendet, verwenden Sie besser das Optionsobjekt. Das entgegengesetzte Beispiel ist so etwas wie eine Funktion, die unendlich viele Argumente erhält wie: setCSS ({height: 100}, {width: 200}, {background: "# 000"}).
quelle
Ich würde mir große Javascript-Projekte ansehen.
Dinge wie Google Map werden Sie häufig sehen, dass instanziierte Objekte ein Objekt erfordern, aber Funktionen Parameter erfordern. Ich würde denken, dass dies mit OPTION-Argumenten zu tun hat.
Wenn Sie Standardargumente oder optionale Argumente benötigen, ist ein Objekt wahrscheinlich besser, weil es flexibler ist. Wenn Sie dies nicht tun, sind normale funktionale Argumente expliziter.
Javascript hat auch ein
arguments
Objekt. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/argumentsquelle