864 Stimmen

Gibt es eine bessere Möglichkeit, optionale Funktionsparameter in JavaScript zu verwenden?

Ich habe optionale Parameter in JavaScript immer wie folgt behandelt:

function myFunc(requiredArg, optionalArg){
  optionalArg = optionalArg || 'defaultValue';

  // Do stuff
}

Gibt es einen besseren Weg, dies zu tun?

Gibt es Fälle, in denen die Verwendung von || wie das scheitern wird?

10 Stimmen

6 Stimmen

Das ist interessant. Übergabe Argumente als ein assoziatives Array scheint ein guter Weg, um mehr als ein paar Argumente zu behandeln.

1 Stimmen

Das ist genau das, was ich in den meisten Fällen tue. Meine Funktionen mit mehr als einem Argument erwarten ein Objektliteral.

1102voto

Paul Dixon Punkte 286600

Ihre Logik schlägt fehl, wenn optionalArg übergeben wird, aber als falsch ausgewertet wird - versuchen Sie dies als Alternative

if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }

Oder eine andere Redewendung:

optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;

Verwenden Sie die Redewendung, die Ihnen die Absicht am besten vermittelt!

84 Stimmen

Ich würde sicherheitshalber die dreifache Gleichung ('...lArg ==="und...') verwenden.

3 Stimmen

@Jarrod === ist bei der typeof-Prüfung nicht erforderlich, da typeof eine Zeichenkette zurückgibt, aber es schadet nicht, dies zu tun.

36 Stimmen

Es ist wahrscheinlich am besten, sich die Verwendung von === zur Gewohnheit zu machen, damit man sich nicht merken muss, unter welchen Umständen es "sicher" ist.

194voto

Lachlan Hunt Punkte 2532

Unter ECMAScript 2015 (auch bekannt als " ES6 ") können Sie in der Funktionsdeklaration Standardwerte für die Argumente angeben:

function myFunc(requiredArg, optionalArg = 'defaultValue') {
    // do stuff
}

Mehr über sie in dieser Artikel auf MDN .

Dies ist derzeit wird nur von Firefox unterstützt Da die Norm jedoch fertiggestellt ist, ist mit einer raschen Verbesserung der Unterstützung zu rechnen.


BEARBEITEN (2019-06-12):

Die Standardparameter werden von modernen Browsern inzwischen weitgehend unterstützt.
Alle Versionen von Internet Entdecker unterstützen diese Funktion nicht. Allerdings, Chrom , Firefox und Kante unterstützen es derzeit.

8 Stimmen

Dies ist für mich Beweis genug, dass JavaScript tatsächlich böse ist. @ThoAppelsin

8 Stimmen

JavaScript ist nur für diejenigen böse, die es nicht verstehen (ich sage nicht, dass Sie es nicht verstehen, aber das ist meine Meinung). Ich denke, es ist Paradigma ist wirklich mächtig im Konzept (Implementierungen sind konsequent immer besser).

9 Stimmen

Oh, hallo Python-Syntax. Schön, Sie wiederzusehen.

126voto

trusktr Punkte 39258

Ich halte dies für die einfachste und am besten lesbare Methode:

if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here

Die Antwort von Paul Dixon ist (meiner bescheidenen Meinung nach) weniger lesenswert als diese, aber das ist eine Frage der Vorliebe.

Die Antwort von insin ist sehr viel fortgeschrittener, aber für große Funktionen sehr viel nützlicher!

EDIT 17.11.2013 21:33 Uhr: Ich habe ein Paket für Node.js erstellt, das es einfacher macht, Funktionen (Methoden) zu überladen, die parametrisch .

3 Stimmen

+1, aber typeof gibt eine Zeichenkette zurück, daher müssen Sie undefined in Anführungszeichen setzen, damit dies funktioniert: if(typeof myVariable == "undefined") ...

3 Stimmen

Ich habe diese Antwort und die akzeptierte Antwort zu einem Kampf auf Leben und Tod gemacht. Die ternäre Methode der akzeptierten Antwort war bei der Handvoll Tests, die ich durchgeführt habe, etwas langsamer: jsperf.com/optional-funktions-parameter-ternary-vs-manual

1 Stimmen

@OmShankar Es wird keinen Unterschied machen.

45voto

Oli Punkte 226885

Wenn Sie eine wörtliche Rede halten müssen NULL dann könnten Sie einige Probleme bekommen. Abgesehen davon, nein, ich denke, Sie sind wahrscheinlich auf dem richtigen Weg.

Die andere Methode, für die sich manche Leute entscheiden, besteht darin, ein assoc-Array von Variablen zu nehmen, das durch die Argumentliste iteriert. Es sieht ein bisschen ordentlicher aus, aber ich kann mir vorstellen, dass es ein kleines (sehr kleines) bisschen mehr Prozess/Speicherintensiv ist.

function myFunction (argArray) {
    var defaults = {
        'arg1'  :   "value 1",
        'arg2'  :   "value 2",
        'arg3'  :   "value 3",
        'arg4'  :   "value 4"
    }

    for(var i in defaults) 
        if(typeof argArray[i] == "undefined") 
               argArray[i] = defaults[i];

    // ...
}

4 Stimmen

Warum nicht hasOwnProperty anstelle von == "undefined" ?

0 Stimmen

Warum nicht if (!(i in argArray)) stattdessen? Und der Vollständigkeit halber, bevor das if -Anweisung sollte eine Prüfung auf den richtigen Argumenttyp erfolgen, z. B. if (typeof argArray !== "object") argArray = []; .

33voto

Idealerweise würde man refaktorisieren, um ein Objekt zu übergeben und zusammenführen mit einem Standardobjekt, so dass die Reihenfolge, in der die Argumente übergeben werden, keine Rolle spielt (siehe den zweiten Abschnitt dieser Antwort, unten).

Wenn Sie jedoch nur etwas schnelles, zuverlässiges, einfach zu benutzendes und nicht sperriges wollen, sollten Sie dies ausprobieren:


Eine saubere Schnelllösung für eine beliebige Anzahl von Standardargumenten

  • Es lässt sich elegant skalieren: minimaler zusätzlicher Code für jede neue Voreinstellung
  • Sie können es überall einfügen: Ändern Sie einfach die Anzahl der erforderlichen Argumente und Variablen
  • Wenn Sie Folgendes bestehen wollen undefined auf ein Argument mit einem Standardwert, so wird die Variable als undefined . Die meisten anderen Optionen auf dieser Seite würden die undefined mit dem Standardwert.

Hier ist ein Beispiel für die Bereitstellung von Standardwerten für drei optionale Argumente (mit zwei erforderlichen Argumenten)

function myFunc( requiredA, requiredB,  optionalA, optionalB, optionalC ) {

  switch (arguments.length - 2) { // 2 is the number of required arguments
    case 0:  optionalA = 'Some default';
    case 1:  optionalB = 'Another default';
    case 2:  optionalC = 'Some other default';
    // no breaks between cases: each case implies the next cases are also needed
  }

}

Einfache Demo . Dies ist vergleichbar mit roenving's Antwort aber leicht erweiterbar für eine beliebige Anzahl von Standardargumenten, einfacher zu aktualisieren und mit arguments no Function.arguments .


Übergabe und Zusammenführung von Objekten für mehr Flexibilität

Der obige Code kann, wie viele andere Methoden zur Übergabe von Standardargumenten, keine Argumente außer der Reihe übergeben, z. B. die Übergabe von optionalC aber verlassen optionalB auf den Standardwert zurückfallen.

Eine gute Möglichkeit dafür ist, Objekte zu übergeben und mit einem Standardobjekt zusammenzuführen. Dies ist auch gut für die Wartbarkeit (achten Sie nur darauf, dass Ihr Code lesbar bleibt, damit zukünftige Mitarbeiter nicht im Unklaren über den möglichen Inhalt der übergebenen Objekte gelassen werden).

Beispiel mit jQuery. Wenn Sie jQuery nicht verwenden, können Sie stattdessen Underscore's _.defaults(object, defaults) o diese Optionen durchsuchen :

function myFunc( args ) {
  var defaults = {
    optionalA: 'Some default',
    optionalB: 'Another default',
    optionalC: 'Some other default'
  };
  args = $.extend({}, defaults, args);
}

Hier ist ein einfaches Beispiel aus der Praxis .

0 Stimmen

Ich bin mir nicht sicher, ob ich diese Frage verstehe. Würde es nicht auch den Wert ersetzen, wenn der Parameter tatsächlich gegeben wird?! Oo

0 Stimmen

Hey, das ist so ziemlich die sauberste Methode, die ich kenne. Das einzige Problem dabei ist folgendes: jsperf.com/optionale-parameter-art-vs-schalter Der Schalter ist offenbar sehr langsam

6 Stimmen

Ich bin mir nicht sicher, ob ich 23,6 Millionen Operationen pro Sekunde als langsam bezeichnen würde... es ist wahr, dass typeof ist unglaublich schnell, aber das bedeutet nicht, dass switch langsam - nur nicht so wahnsinnig schnell.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X