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.

19voto

roenving Punkte 2464

Sie können dafür verschiedene Schemata verwenden. Ich habe immer auf arguments.length getestet:

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

  ...

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

Und dann lieferte Paul ein misslungenes Szenario !-)

0 Stimmen

Ich bin überrascht, dass noch niemand die Verwendung des Argumentenfeldes erwähnt hat!

2 Stimmen

Was ist das "eine fehlgeschlagene Szenario"? Wenn Sie false, null, 0 usw. übergeben, ändert sich die Länge des Argument-Arrays nicht. Ansonsten ist die Verwendung mit switch(myFunc.arguments.length) gut und flexibel.

0 Stimmen

Oh, ich verstehe - Sie meinten ein Scheiternszenario im OP, nicht ein Scheiternszenario mit Ihrer Lösung.

14voto

Jonny Buchanan Punkte 60128

Ähnlich wie bei der Antwort von 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 man noch ein bisschen schöner machen.

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 das Schöne an dieser Methode?

  • Sie können so viele Argumente weglassen, wie Sie möchten - wenn Sie nur den Wert eines Arguments überschreiben möchten, können Sie nur dieses Argument angeben, anstatt explizit die undefined wenn, sagen wir, es gibt 5 Argumente und Sie wollen nur das letzte anpassen, wie Sie es bei einigen der anderen vorgeschlagenen Methoden tun müssten.
  • Wenn Sie mit einer Konstruktorfunktion für ein Objekt arbeiten, das von einem anderen Objekt erbt, ist es einfach, alle Argumente zu akzeptieren, die vom Konstruktor des Objekts, von dem Sie erben, benötigt werden, da Sie diese Argumente in Ihrer Konstruktorsignatur nicht benennen oder sogar Ihre eigenen Standardwerte angeben müssen (lassen Sie das den Konstruktor des übergeordneten Objekts für Sie tun, wie oben gesehen, wenn CharField ruft auf. Field 's Konstruktor).
  • Untergeordnete Objekte in Vererbungshierarchien können die Argumente für ihren übergeordneten Konstruktor nach eigenem Ermessen anpassen, indem sie ihre eigenen Standardwerte durchsetzen oder sicherstellen, dass ein bestimmter Wert immer verwendet werden.

1 Stimmen

Ich hasse komplexe Funktionen und lange Dokumente.

9voto

Petr Hurtak Punkte 2161

Lose Typenprüfung

Leicht zu schreiben, aber 0 , '' , false , null y undefined wird in einen Standardwert umgewandelt, was möglicherweise nicht das erwartete Ergebnis ist.

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

Strenge Typenprüfung

Länger, deckt aber die meisten Fälle ab. Der einzige Fall, in dem es fälschlicherweise einen Standardwert zuweist, ist, wenn wir undefined als Parameter.

function myFunc(requiredArg, optionalArg) {
    optionalArg = typeof optionalArg !== 'undefined' ? optionalArg : 'defaultValue';
}

Variable Argumente prüfen

Fängt alle Fälle ab, ist aber am schwerfälligsten zu schreiben.

function myFunc(requiredArg, optionalArg1, optionalArg2) {
    optionalArg1 = arguments.length > 1 ? optionalArg1 : 'defaultValue';
    optionalArg2 = arguments.length > 2 ? optionalArg2 : 'defaultValue';
}

ES6

Leider ist die Browserunterstützung im Moment sehr schlecht

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

}

0 Stimmen

"Checking arguments variable - Fängt alle Fälle ab, ist aber am schwerfälligsten zu schreiben" Und im losen Modus können negative Auswirkungen auf die Leistung durch die Verwendung von arguments (nicht, dass das normalerweise wichtig wäre).

8voto

Vitim.us Punkte 18320

Wenn Sie ausgiebig mit Standardwerten arbeiten, scheint dies viel besser lesbar zu sein:

function usageExemple(a,b,c,d){
    //defaults
    a=defaultValue(a,1);
    b=defaultValue(b,2);
    c=defaultValue(c,4);
    d=defaultValue(d,8);

    var x = a+b+c+d;
    return x;
}

Deklarieren Sie diese Funktion einfach auf dem globalen Escope.

function defaultValue(variable,defaultValue){
    return(typeof variable!=='undefined')?(variable):(defaultValue);
}

Verwendungsmuster fruit = defaultValue(fruit,'Apple');

*PS können Sie die defaultValue Funktion zu einem kurzen Namen zu machen, verwenden Sie einfach nicht default Es ist ein reserviertes Wort in Javascript.

0 Stimmen

+1, denn ich wollte meine Lösung posten, die genau dasselbe ist: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }

6voto

Yann Bertrand Punkte 3063

Mit ES2015/ES6 können Sie die folgenden Vorteile nutzen Object.assign die ersetzen können $.extend() o _.defaults()

function myFunc(requiredArg, options = {}) {
  const defaults = {
    message: 'Hello',
    color: 'red',
    importance: 1
  };

  const settings = Object.assign({}, defaults, options);

  // do stuff
}

Sie können auch Standardargumente wie diese verwenden

function myFunc(requiredArg, { message: 'Hello', color: 'red', importance: 1 } = {}) {
  // do stuff
}

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