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.

1voto

Imagine Breaker Punkte 2072
function Default(variable, new_value)
{
    if(new_value === undefined) { return (variable === undefined) ? null : variable; }
    return (variable === undefined) ? new_value : variable;
}

var a = 2, b = "hello", c = true, d;

var test = Default(a, 0),
test2 = Default(b, "Hi"),
test3 = Default(c, false),
test4 = Default(d, "Hello world");

window.alert(test + "\n" + test2 + "\n" + test3 + "\n" + test4);

http://jsfiddle.net/mq60hqrf/

1voto

mcfedr Punkte 7335
  1. arg || 'default' ist ein guter Weg und funktioniert in 90 % der Fälle

  2. Es schlägt fehl, wenn Sie Werte übergeben müssen, die "falsch" sein könnten

    • false
    • 0
    • NaN
    • ""

    In diesen Fällen müssen Sie etwas ausführlicher sein und nach undefined

  3. Seien Sie auch vorsichtig, wenn Sie optionale Argumente an erster Stelle haben, Sie müssen sich der Typen aller Ihrer Argumente bewusst sein

1voto

Duco L Punkte 299

Hier ist meine Lösung. Bei dieser Lösung können Sie jeden beliebigen Parameter weglassen. Die Reihenfolge der optionalen Parameter ist nicht wichtig, und Sie können benutzerdefinierte Validierung hinzufügen.

function YourFunction(optionalArguments) {
            //var scope = this;

            //set the defaults
            var _value1 = 'defaultValue1';
            var _value2 = 'defaultValue2';
            var _value3 = null;
            var _value4 = false;

            //check the optional arguments if they are set to override defaults...
            if (typeof optionalArguments !== 'undefined') {

                if (typeof optionalArguments.param1 !== 'undefined')
                    _value1 = optionalArguments.param1;

                if (typeof optionalArguments.param2 !== 'undefined')
                    _value2 = optionalArguments.param2;

                if (typeof optionalArguments.param3 !== 'undefined')
                    _value3 = optionalArguments.param3;

                if (typeof optionalArguments.param4 !== 'undefined')
                    //use custom parameter validation if needed, in this case for javascript boolean
                   _value4 = (optionalArguments.param4 === true || optionalArguments.param4 === 'true');
            }

            console.log('value summary of function call:');
            console.log('value1: ' + _value1);
            console.log('value2: ' + _value2);
            console.log('value3: ' + _value3);
            console.log('value4: ' + _value4);
            console.log('');
        }

        //call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
        YourFunction({
            param1: 'yourGivenValue1',
            param2: 'yourGivenValue2',
            param3: 'yourGivenValue3',
            param4: true,
        });

        //order is not important
        YourFunction({
            param4: false,
            param1: 'yourGivenValue1',
            param2: 'yourGivenValue2',
        });

        //uses all default values
        YourFunction();

        //keeps value4 false, because not a valid value is given
        YourFunction({
            param4: 'not a valid bool'
        });

0voto

Bekim Bacaj Punkte 5223

Es scheint, dass es am sichersten ist, sich mit allen verfälschte Typen der gelieferten Argumente bevor Sie sich für die Verwendung der Standard - ist die Prüfung der Existenz \presence der optionales Argument in der aufgerufenen Funktion.

Auf der Grundlage des Objekts arguments object member creation, das nicht einmal erstellt wird, wenn das Argument fehlt, unabhängig von der Tatsache, dass es deklariert werden könnte, können wir Ihre Funktion wie folgt schreiben:

  function myFunc(requiredArg, optionalArg){
        optionalArg = 1 in arguments ? optionalArg : 'defaultValue';
  //do stuff
  }

Dieses Verhalten ausnutzen: Wir können beliebig und explizit auf fehlende Werte in der Argumentliste prüfen, wenn wir sicherstellen müssen, dass die Funktion einen bestimmten Wert erhält, der in ihrer Prozedur benötigt wird.

Im folgenden Democode werden wir absichtlich eine typlos y wertlos undefiniert als Standardwert, um feststellen zu können, ob es bei falschen Argumentwerten wie 0 false usw. fehlschlägt oder ob es sich wie erwartet verhält.

function argCheck( arg1, arg2, arg3 ){

       arg1 = 0 in arguments || undefined;
       arg2 = 1 in arguments || false;
       arg3 = 2 in arguments || 0;
   var arg4 = 3 in arguments || null;

   console.log( arg1, arg2, arg3, arg4 ) 
}

Nun werden einige falsche Argumente daraufhin überprüft, ob ihr Vorhandensein korrekt erkannt wurde und daher zu wahr :

argCheck( "", 0, false, null );
>> true true true true

Das bedeutet, dass sie bei der Erkennung von/als erwartete(n) Argumente(n) nicht versagt haben. Hier haben wir eine Prüfung, bei der alle Argumente fehlen, die nach unserem Algo ihre Standardwerte annehmen sollten, auch wenn sie falsy .

argCheck( );
>> undefined false 0 null

Wie wir sehen können, sind die Argumente arg1, arg2, arg3 und die nicht deklarierte arg4 geben ihre genauen Standard Werte, wie bestellt. Da wir nun sichergestellt haben, dass es funktioniert, können wir die Funktion umschreiben, die sie tatsächlich wie im ersten Beispiel verwenden kann, indem wir: entweder wenn oder eine ternär Zustand.

Bei Funktionen, die mehr als ein optionales Argument haben, - eine Schleife durch, könnte uns einige Bits gespart haben. Aber da das Argument Namen werden nicht initialisiert, wenn ihre Werte nicht geliefert werden, wir können nicht mehr über Namen auf sie zugreifen, selbst wenn wir programmatisch einen Standardwert geschrieben haben, wir können nur über argumente[index] was für die Lesbarkeit des Codes unbrauchbar ist.

Aber abgesehen von dieser Unannehmlichkeit, die in bestimmten Kodierungssituationen durchaus akzeptabel sein könnte, gibt es noch ein anderes, nicht berücksichtigtes Problem für die mehrfache und beliebige Anzahl von Argumentvorgaben. Dies kann und sollte als Fehler angesehen werden, da wir nicht mehr Argumente überspringen können, wie es früher möglich war, ohne einen Wert anzugeben, in einer Syntax wie:

argCheck("a",,22,{});

denn er wird werfen! Das macht es uns unmöglich, unser Argument durch eine spezifische falsy Typ des gewünschten Standardwerts. Das ist dumm, denn die Argumente Objekt ist ein Array-ähnliches Objekt und es wird erwartet, dass es diese Syntax und Konvention unterstützt, entweder von Haus aus oder standardmäßig!

Aufgrund dieser kurzsichtigen Entscheidung können wir nicht mehr darauf hoffen, eine Funktion wie diese zu schreiben:

function argCheck( ) {
    var _default = [undefined, 0, false, null ],
        _arg = arguments;

 for( var x in _default ) {
         x in _arg ? 1 : _arg[x] = _default[x];
        }
    console.log( _arg[0],_arg[1],_arg[2],_arg[3] );
}

in diesem Fall könnten wir jeden Standardwert eines gewünschten Typs in die Zeile arguments schreiben und zumindest über args.index auf sie zugreifen.

Dieser Funktionsaufruf würde zum Beispiel Folgendes ergeben:

argCheck();
>>undefined 0 false null

wie in unserem Standard-Array von Argumenten definiert. Das Folgende ist jedoch weiterhin möglich:

argCheck({})
>>Object {  } 0 false null

argCheck({}, [])
>>Object {  } Array [  ] false null

Aber leider nicht:

 argCheck("a",,,22);
 >>SyntaxError: expected expression, got ','

Das wäre sonst eine Protokollierung:

>>a 0 false 22

aber das ist in einer besseren Welt! Aber für die ursprüngliche Frage reicht die oberste Funktion völlig aus. z.B.:

function argCheck( arg, opt ) {
         1 in arguments ? 1 : opt = "default";
         console.log( arg, opt );
}

p.s.: Entschuldigung, dass ich die Typen der gewählten Standardwerte in meinen Argumenten, während ich sie schreibe.

0 Stimmen

Ein JavaScript-Analphabet hat soeben die beste und vollständigste Antwort zu diesem Thema heruntergestimmt, ohne überhaupt zu wissen, warum. Vielleicht, weil sie zu ausführlich ist und im Prozess verloren gegangen ist. Mehr Glück beim nächsten Mal, mit Ihren Lese- und Verständnisfähigkeiten :)

0 Stimmen

Es gibt viele Gründe für eine Herabstufung, und niemand schuldet Ihnen eine Erklärung, warum er dies getan hat. Nimm es nicht zu persönlich, das ist nicht konstruktiv und sieht schlecht aus.

0 Stimmen

Der Hauptgrund von "vielen Gründen" ist - in diesem Fall - ein radikaler JavaScript-Ignorant zu sein - Wie über Ihre unscheinbare falsche Bemerkung, dass niemand eine Erklärung für eine gelegentlich "dumme" Herabstufung schuldet, ist falsch - denn soweit ich mich erinnere, als ich das erste Mal meinte, herabstufen zu müssen, verlangte / wies mich die SO-Politik an, auch eine Erklärung für die Herabstufung zu geben.

0voto

Brian McCutchon Punkte 7989

Korrigieren Sie mich, wenn ich falsch liege, aber dies scheint der einfachste Weg zu sein (zumindest für ein Argument):

function myFunction(Required,Optional)
{
    if (arguments.length<2) Optional = "Default";
    //Your code
}

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