Frage Gibt es eine bessere Möglichkeit, optionale Funktionsparameter in JavaScript auszuführen? [Duplikat]


Diese Frage hat hier bereits eine Antwort:

Ich habe immer optionale Parameter in JavaScript wie folgt behandelt:

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

  // Do stuff
}

Gibt es einen besseren Weg, es zu tun?

Gibt es Fälle, in denen verwendet wird? || wie wird das scheitern?


756
2017-09-29 14:27


Ursprung


Antworten:


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 ein alternatives Idiom:

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

Verwenden Sie, welches Idiom die Absicht kommuniziert, die zu Ihnen am besten ist!


1012
2017-09-29 14:30



Ich finde dies die einfachste und lesbarste Methode:

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

Paul Dixons Antwort (meiner bescheidenen Meinung nach) ist weniger leserlich als diese, aber es kommt auf die Präferenz an.

Insins Antwort ist viel fortgeschrittener, aber viel nützlicher für große Funktionen!

EDIT 17.11.2013 21.33 Uhr: Ich habe ein Paket für Node.js erstellt, das es erleichtert, Funktionen (Methoden) zu "überladen" parametrisch.


125
2017-11-14 21:23



In ECMAScript 2015 (auch bekannt als "ES6") können Sie Standard-Argumentwerte in der Funktionsdeklaration deklarieren:

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

Mehr über sie in Dieser Artikel auf MDN (Ungeachtet des Artikeltitels werden sie in JavaScript als "Argumente" und nicht als "Parameter" bezeichnet).

Dies ist derzeit nur von Firefox unterstützt, aber nach Abschluss des Standards erwarten Sie, dass sich die Unterstützung schnell verbessert.


119
2018-02-19 13:13



Wenn du einen Literal hinkriegen musst NULL in, dann könntest du ein paar Probleme haben. Abgesehen davon, nein, ich denke du bist wahrscheinlich auf dem richtigen Weg.

Die andere Methode, die manche Leute wählen, ist ein assoziatives Array von Variablen, die durch die Argumentliste laufen. Es sieht etwas ordentlicher aus, aber ich kann mir vorstellen, dass es ein wenig (sehr wenig) 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];

    // ...
}

44
2017-09-29 14:34



Im Idealfall würden Sie ein Objekt umformen und verschmelzen Wenn ein Standardobjekt verwendet wird, spielt die Reihenfolge, in der die Argumente übergeben werden, keine Rolle (siehe den zweiten Abschnitt dieser Antwort unten).

Wenn Sie jedoch nur etwas schnell, zuverlässig, einfach zu bedienen und nicht sperrig möchten, versuchen Sie Folgendes:


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

  • Es skaliert elegant: minimaler zusätzlicher Code für jeden neuen Standard
  • Sie können es überall einfügen: Ändern Sie einfach die Anzahl der benötigten Argumente und Variablen
  • Wenn du gehen willst undefined Zu einem Argument mit einem Standardwert wird die Variable auf diese Weise als festgelegt undefined. Die meisten anderen Optionen auf dieser Seite würden ersetzen 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. Das ist ähnlich wie Rönvings Antwort, aber leicht erweiterbar für eine beliebige Anzahl von Standardargumenten, einfacher zu aktualisieren und verwenden arguments nicht Function.arguments.


Übergeben und Zusammenführen von Objekten für mehr Flexibilität

Der obige Code kann, wie viele Arten, Standardargumente auszuführen, Argumente nicht aus der Reihenfolge übergeben, z optionalCaber verlassen optionalB um auf den Standardwert zurückzugreifen.

Eine gute Option dafür ist das Übergeben von Objekten und das Zusammenführen mit einem Standardobjekt. Dies ist auch gut für die Wartbarkeit (achten Sie einfach darauf, Ihren Code lesbar zu halten, damit zukünftige Mitarbeiter nicht über den möglichen Inhalt der Objekte, die Sie weitergeben, raten können).

Beispiel mit jQuery. Wenn Sie jQuery nicht verwenden, können Sie stattdessen Underscore verwenden _.defaults(object, defaults) oder Durchsuchen Sie diese Optionen:

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

Hier ist Ein einfaches Beispiel dafür.


32
2018-02-20 15:36



Sie können dafür verschiedene Schemata verwenden. Ich habe immer nach Argumenten getestet.

function myFunc(requiredArg, optionalArg){
  optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;

  ...

- dabei kann es unmöglich scheitern, aber ich weiß nicht, ob dein Weg eine Chance hat, zu versagen, gerade jetzt kann ich mir kein Szenario ausdenken, wo es tatsächlich scheitern würde ...

Und dann lieferte Paul ein scheiterndes Szenario! -)


17
2017-09-29 14:33



Ähnlich wie bei Oli verwende ich ein Argument Object und ein Object, das die Standardwerte definiert. Mit ein bisschen Zucker ...

/**
 * Updates an object's properties with other objects' properties. All
 * additional non-falsy arguments will have their properties copied to the
 * destination object, in the order given.
 */
function extend(dest) {
  for (var i = 1, l = arguments.length; i < l; i++) {
    var src = arguments[i]
    if (!src) {
      continue
    }
    for (var property in src) {
      if (src.hasOwnProperty(property)) {
        dest[property] = src[property]
      }
    }
  }
  return dest
}

/**
 * Inherit another function's prototype without invoking the function.
 */
function inherits(child, parent) {
  var F = function() {}
  F.prototype = parent.prototype
  child.prototype = new F()
  child.prototype.constructor = child
  return child
}

... das kann etwas netter gemacht werden.

function Field(kwargs) {
  kwargs = extend({
    required: true, widget: null, label: null, initial: null,
    helpText: null, errorMessages: null
  }, kwargs)
  this.required = kwargs.required
  this.label = kwargs.label
  this.initial = kwargs.initial
  // ...and so on...
}

function CharField(kwargs) {
  kwargs = extend({
    maxLength: null, minLength: null
  }, kwargs)
  this.maxLength = kwargs.maxLength
  this.minLength = kwargs.minLength
  Field.call(this, kwargs)
}
inherits(CharField, Field)

Was ist schön an dieser Methode?

  • Sie können beliebig viele Argumente auslassen. Wenn Sie nur den Wert eines Arguments überschreiben möchten, können Sie dieses Argument einfach angeben, anstatt explizit übergeben zu müssen undefined wenn, sagen wir, es gibt 5 Argumente, und Sie wollen nur die letzte anpassen, wie Sie mit einigen der anderen vorgeschlagenen Methoden tun müssten.
  • Bei der Arbeit mit einer Konstruktor-Funktion für ein Objekt, das von einem anderen Objekt erbt, können Argumente, die vom Konstruktor des Objekts, von dem Sie vererbt werden, benötigt werden, leicht akzeptiert werden, da Sie diese Argumente in Ihrer Konstruktorsignatur nicht benennen müssen. oder stellen Sie sogar Ihre eigenen Standardwerte bereit (lassen Sie den Konstruktor des übergeordneten Objekts das für Sie tun, wie oben zu sehen) CharField Anrufe Field's Konstruktor).
  • Untergeordnete Objekte in Vererbungshierarchien können Argumente für ihren übergeordneten Konstruktor nach eigenem Ermessen anpassen, indem sie ihre eigenen Standardwerte durchsetzen oder sicherstellen, dass ein bestimmter Wert verwendet wird immer verwendet werden.

13
2017-09-29 23:16