Gibt es eine bessere Möglichkeit, optionale functionsparameter in JavaScript auszuführen?

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 || ? wie wird das scheitern?

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!

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 functionen!

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

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

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

Mehr über sie in diesem Artikel auf MDN (trotz des Artikels Titel, sie heißen “Argumente”, nicht “Parameter” in JavaScript).

Dies wird derzeit nur von Firefox unterstützt , aber sobald der Standard erfüllt ist, erwarten Sie eine schnelle Verbesserung der Unterstützung.

Wenn Sie einen literalen NULL Wert NULL , könnten Sie einige 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]; // ... } 

Idealerweise würden Sie ein Objekt refaktorisieren und es mit einem Standardobjekt zusammenführen, 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 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 Sie undefined in ein Argument mit einem Standardwert übergeben möchten, wird die Variable auf diese Weise als nicht undefined . Die meisten anderen Optionen auf dieser Seite würden undefined durch den Standardwert ersetzen.

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 der Antwort von roenving ähnlich, aber leicht erweiterbar für eine beliebige Anzahl von Standardargumenten, leichter zu aktualisieren und mit arguments nicht mit Function.arguments .


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

Der obige Code kann, wie viele andere Möglichkeiten, Standardargumente auszuführen, Argumente nicht außerhalb der Reihenfolge übergeben, z. B. indem sie optionalC aber optionalB , um auf ihren 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 die _.defaults(object, defaults) Underscore verwenden oder 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 in Aktion .

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! -)

Ä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 weglassen. Wenn Sie nur den Wert eines Arguments überschreiben möchten, können Sie einfach dieses Argument angeben, anstatt explizit undefined wenn, sagen wir, es fünf Argumente gibt und Sie nur das Argument anpassen möchten Letzteres, wie Sie mit einigen der anderen vorgeschlagenen Methoden tun müssten.
  • Bei der Arbeit mit einer Konstruktor-function 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, wenn CharField den CharField aufruft).
  • Untergeordnete Objekte in inheritanceshierarchien können Argumente für ihren übergeordneten Konstruktor nach eigenem Ermessen anpassen, indem sie ihre eigenen Standardwerte durchsetzen oder sicherstellen, dass immer ein bestimmter Wert verwendet wird.

Wenn Sie umfangreiche Standardwerte verwenden, scheint dies wesentlich lesbarer 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; } 

Erklären Sie diese function einfach auf dem globalen escope.

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

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

* PS du kannst die defaultValue function in einen kurzen Namen umbenennen, defaultValue einfach nicht default es ist ein reserviertes Wort in Javascript.

Lockere Typprüfung

Einfach zu schreiben, aber 0 , '' , false , null und undefined werden in den Standardwert konvertiert, der nicht erwartet werden kann.

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

Strikte Typprüfung

Länger, aber deckt die Mehrheit der Fälle ab. Der einzige Fall, in dem der Standardwert falsch zugewiesen wird, ist, wenn wir undefined als Parameter übergeben.

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

Überprüfung der Argumentvariablen

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

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

ES6

Leider hat dies zur Zeit sehr schlechte Browser-Unterstützung

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

Mit ES2015 / ES6 können Sie die Object.assign die $.extend() oder _.defaults() ersetzen kann

 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 diesen verwenden

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

Wenn Sie die Underscore- Bibliothek verwenden (sollten Sie, es ist eine wunderbare Bibliothek):

 _.defaults(optionalArg, 'defaultValue'); 

Ich bin es gewohnt, ein paar grundlegende Variationen im Umgang mit optionalen Variablen zu sehen. Manchmal sind die entspannten Versionen nützlich.

 function foo(a, b, c) { a = a || "default"; // Matches 0, "", null, undefined, NaN, false. a || (a = "default"); // Matches 0, "", null, undefined, NaN, false. if (b == null) { b = "default"; } // Matches null, undefined. if (typeof c === "undefined") { c = "default"; } // Matches undefined. } 

Der für die Variable a verwendete Voreinstellungserrors wird beispielsweise in Backbone.js ausführlich verwendet.

Geleitet auf diese Frage, Suche nach Standard-Parameter in EcmaScript 2015 , so nur zu erwähnen …

Mit ES6 können wir Standardparameter verwenden :

 function doSomething(optionalParam = "defaultValue"){ console.log(optionalParam);//not required to check for falsy values } doSomething(); //"defaultValue" doSomething("myvalue"); //"myvalue" 

Während eines Projekts bemerkte ich, dass ich mich mit den optionalen Parametern und Einstellungen zu sehr wiederholte, also habe ich eine class erstellt, die die Typprüfung durchführt und einen Standardwert zuweist, der sauberen und lesbaren Code ergibt. Siehe Beispiel und lassen Sie mich wissen, ob das für Sie funktioniert.

 var myCar = new Car('VW', {gearbox:'automatic', options:['radio', 'airbags 2x']}); var myOtherCar = new Car('Toyota'); function Car(brand, settings) { this.brand = brand; // readable and adjustable code settings = DefaultValue.object(settings, {}); this.wheels = DefaultValue.number(settings.wheels, 4); this.hasBreaks = DefaultValue.bool(settings.hasBreaks, true); this.gearbox = DefaultValue.string(settings.gearbox, 'manual'); this.options = DefaultValue.array(settings.options, []); // instead of doing this the hard way settings = settings || {}; this.wheels = (!isNaN(settings.wheels)) ? settings.wheels : 4; this.hasBreaks = (typeof settings.hasBreaks !== 'undefined') ? (settings.hasBreaks === true) : true; this.gearbox = (typeof settings.gearbox === 'string') ? settings.gearbox : 'manual'; this.options = (typeof settings.options !== 'undefined' && Array.isArray(settings.options)) ? settings.options : []; } 

Mit dieser class:

 (function(ns) { var DefaultValue = { object: function(input, defaultValue) { if (typeof defaultValue !== 'object') throw new Error('invalid defaultValue type'); return (typeof input !== 'undefined') ? input : defaultValue; }, bool: function(input, defaultValue) { if (typeof defaultValue !== 'boolean') throw new Error('invalid defaultValue type'); return (typeof input !== 'undefined') ? (input === true) : defaultValue; }, number: function(input, defaultValue) { if (isNaN(defaultValue)) throw new Error('invalid defaultValue type'); return (typeof input !== 'undefined' && !isNaN(input)) ? parseFloat(input) : defaultValue; }, // wrap the input in an array if it is not undefined and not an array, for your convenience array: function(input, defaultValue) { if (typeof defaultValue === 'undefined') throw new Error('invalid defaultValue type'); return (typeof input !== 'undefined') ? (Array.isArray(input) ? input : [input]) : defaultValue; }, string: function(input, defaultValue) { if (typeof defaultValue !== 'string') throw new Error('invalid defaultValue type'); return (typeof input === 'string') ? input : defaultValue; }, }; ns.DefaultValue = DefaultValue; }(this)); 

Ich weiß nicht, warum @ Pauls Antwort abgelehnt wird, aber die validation gegen null ist eine gute Wahl. Vielleicht wird ein positiveres Beispiel sinnvoller:

In JavaScript ist ein verpasster Parameter wie eine deklarierte Variable, die nicht initialisiert wird (nur var a1; ). Und der Gleichheitsoperator konvertiert das Undefinierte in Null, so dass dies sowohl mit Werttypen als auch mit Objekten hervorragend funktioniert, und so behandelt CoffeeScript optionale Parameter.

 function overLoad(p1){ alert(p1 == null); // Caution, don't use the strict comparison: === won't work. alert(typeof p1 === 'undefined'); } overLoad(); // true, true overLoad(undefined); // true, true. Yes, undefined is treated as null for equality operator. overLoad(10); // false, false function overLoad(p1){ if (p1 == null) p1 = 'default value goes here...'; //... } 

Es gibt jedoch Bedenken, dass für die beste Semantik typeof variable === 'undefined' etwas besser ist. Ich werde das nicht verteidigen, da es um die zugrunde liegende API geht, wie eine function implementiert wird; Es sollte den API-Benutzer nicht interessieren.

Ich sollte auch hinzufügen, dass dies die einzige Möglichkeit ist, physisch sicherzustellen, dass irgendein Argument übersehen wurde, indem der in Operator verwendet wird, der leider nicht mit den Parameternamen arbeitet, also einen Index der arguments .

 function foo(a, b) { // Both a and b will evaluate to undefined when used in an expression alert(a); // undefined alert(b); // undefined alert("0" in arguments); // true alert("1" in arguments); // false } foo (undefined); 

Der Test auf undefined ist unnötig und nicht so robust, wie es sein könnte, weil, wie Benutzer568458 hervorhob, die gelieferte Lösung fehlschlägt, wenn null oder falsch übergeben wird. Benutzer Ihrer API könnten fälschlicherweise für falsch oder null erachten, dass die Methode diesen Parameter vermeiden würde.

 function PaulDixonSolution(required, optionalArg){ optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg; console.log(optionalArg); }; PaulDixonSolution("required"); PaulDixonSolution("required", "provided"); PaulDixonSolution("required", null); PaulDixonSolution("required", false); 

Das Ergebnis ist:

 defaultValue provided null false 

Die letzten beiden sind möglicherweise schlecht. Versuchen Sie stattdessen:

 function bulletproof(required, optionalArg){ optionalArg = optionalArg ? optionalArg : "defaultValue";; console.log(optionalArg); }; bulletproof("required"); bulletproof("required", "provided"); bulletproof("required", null); bulletproof("required", false); 

Was dazu führt:

 defaultValue provided defaultValue defaultValue 

Das einzige Szenario, in dem dies nicht optimal ist, ist, wenn Sie tatsächlich optionale Parameter haben, die als boolesche Werte oder als absichtliche Null definiert werden sollen.

Ich habe einige der hier erwähnten Optionen ausprobiert und die performance getestet. In diesem Moment scheint der logische oder der schnellste zu sein. Obwohl dies im Laufe der Zeit geändert wird (verschiedene Versionen von JavaScript-Engines).

Dies sind meine Ergebnisse (Microsoft Edge 20.10240.16384.0):

 Function executed Operations/sec Statistics TypeofFunction('test'); 92,169,505 ±1.55% 9% slower SwitchFuntion('test'); 2,904,685 ±2.91% 97% slower ObjectFunction({param1: 'test'}); 924,753 ±1.71% 99% slower LogicalOrFunction('test'); 101,205,173 ±0.92% fastest TypeofFunction2('test'); 35,636,836 ±0.59% 65% slower 

Dieser performancestest kann leicht repliziert werden unter: http://jsperf.com/optional-parameters-typeof-vs-switch/2

Dies ist der Code des Tests:

   

Das ist, womit ich endete:

 function WhoLikesCake(options) { options = options || {}; var defaultOptions = { a : options.a || "Huh?", b : options.b || "I don't like cake." } console.log('a: ' + defaultOptions.b + ' - b: ' + defaultOptions.b); // Do more stuff here ... } 

Genannt wie folgt:

 WhoLikesCake({ b : "I do" }); 

Leute –

Nachdem ich mir diese und andere Lösungen angeschaut habe, habe ich eine Anzahl von ihnen ausprobiert, indem ich ein Codeschnipsel von W3Schools als Basis benutzte. Sie können herausfinden, was im Folgenden funktioniert. Jedes der Elemente, die auskommentiert werden, funktioniert ebenfalls und ermöglicht es Ihnen, einfach durch Entfernen einzelner Kommentare zu experimentieren. Um es klar zu sagen, ist es der Parameter “eyecolor”, der nicht definiert wird.

 function person(firstname, lastname, age, eyecolor) { this.firstname = firstname; this.lastname = lastname; this.age = age; this.eyecolor = eyecolor; // if(null==eyecolor) // this.eyecolor = "unknown1"; //if(typeof(eyecolor)==='undefined') // this.eyecolor = "unknown2"; // if(!eyecolor) // this.eyecolor = "unknown3"; this.eyecolor = this.eyecolor || "unknown4"; } var myFather = new person("John", "Doe", 60); var myMother = new person("Sally", "Rally", 48, "green"); var elem = document.getElementById("demo"); elem.innerHTML = "My father " + myFather.firstname + " " + myFather.lastname + " is " + myFather.age + " with " + myFather.eyecolor + " eyes.
" + "My mother " + myMother.firstname + " " + myMother.lastname + " is " + myMother.age + " with " + myMother.eyecolor + " eyes.";
 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/

Hier ist meine Lösung. Damit können Sie beliebige Parameter belassen. Die Reihenfolge der optionalen Parameter ist nicht wichtig und Sie können eine benutzerdefinierte validation 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' }); 
  1. arg || 'default' arg || 'default' ist eine gute Möglichkeit und funktioniert in 90% der Fälle

  2. Es schlägt fehl, wenn Sie Werte übergeben müssen, die “falsch” sind.

    • false
    • 0
    • NaN
    • ""

    Für diese Fälle müssen Sie etwas ausführlicher sein und nach undefined

  3. Seien Sie vorsichtig, wenn Sie zuerst optionale Argumente haben. Sie müssen sich der Art aller Ihrer Argumente bewusst sein

Korrigiere mich, wenn ich falsch liege, aber das scheint der einfachste Weg zu sein (für ein Argument jedenfalls):

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

Diese sind kürzer als die Typeof Operator-Version.

 function foo(a, b) { a !== undefined || (a = 'defaultA'); if(b === undefined) b = 'defaultB'; ... } 

Es scheint, dass der sicherste Weg – sich mit allen möglichen Arten von gelieferten Argumenten zu beschäftigen, bevor man sich entscheidet, den Standard zu verwenden – darin besteht, nach dem Vorhandensein des optionalen Arguments in der aufgerufenen function zu suchen.

Gestützt auf die Erstellung des Arguments articles object, das nicht einmal erstellt wird, wenn das Argument fehlt, unabhängig von der Tatsache, dass es möglicherweise deklariert wird, können wir Ihre function folgendermaßen schreiben:

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

Verwenden dieses Verhaltens: Wir können alle fehlenden Werte in der Argumentenliste sicher und explizit überprüfen, wenn wir sicherstellen müssen, dass die function einen bestimmten Wert für ihre Prozedur erhält.

Im folgenden Demo-Code werden wir absichtlich einen typlosen und wertlosen undefinierten Wert als Standardwert angeben, um zu bestimmen, ob er bei falschen Argumentwerten wie 0 false usw. fehlschlagen kann oder ob er 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 ) } 

Überprüfen Sie nun einige falsche Argument-Werte, um zu sehen, ob ihre Anwesenheit korrekt erkannt wird, und wird daher als wahr ausgewertet:

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

Das bedeutet, dass sie die Erkennung von / als erwartete Argumentwerte nicht fehlschlagen. Hier haben wir einen Check mit allen fehlenden Argumenten, die laut unserem Algorithmus auch dann ihre Defaultwerte erhalten sollten, wenn sie falsch sind .

 argCheck( ); >> undefined false 0 null 

Wie wir sehen können, geben die Argumente arg1, arg2, arg3 und das nicht deklarierte arg4 ihre genauen Standardwerte zurück . Da wir nun sichergestellt haben, dass es funktioniert, können wir die function neu schreiben, die sie tatsächlich wie im ersten Beispiel verwenden kann: entweder if oder eine ternäre Bedingung.

Auf functionen, die mehr als ein optionales Argument haben, – eine Durchschleifung, könnten uns einige Bits gespart haben. Aber da Argumentnamen nicht initialisiert werden, wenn ihre Werte nicht geliefert werden, können wir nicht mehr auf Namen zugreifen, selbst wenn wir programmatisch einen Standardwert geschrieben haben, können wir nur durch Argumente [index] darauf zugreifen, welche unbrauchbare Codelesbarkeitsweise.

Aber abgesehen von dieser Unannehmlichkeit, die in bestimmten Kodierungssituationen völlig akzeptabel sein könnte, gibt es ein weiteres unerklärtes Problem für mehrere und willkürliche Anzahl von Argumentvorgaben. Das kann und sollte als ein Fehler betrachtet werden, da wir Argumente nicht mehr überspringen können, wie wir es früher hätten tun können, ohne einen Wert anzugeben, in einer Syntax wie:

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

weil es casting wird! Das macht es unmöglich, unser Argument durch einen bestimmten Falsytyp unseres gewünschten Defaultwertes zu ersetzen . Das ist dumm, da das arguments-Objekt ein array-ähnliches Objekt ist und diese Syntax und Konvention standardmäßig oder standardmäßig unterstützt!

Aufgrund dieser kurzsichtigen Entscheidung können wir nicht mehr hoffen, eine function 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 wären wir in der Lage, jeden Standardwert eines gewünschten Typs in der Argumentenzeile zu schreiben und zumindest auf sie durch args.index zugreifen zu können.

Zum Beispiel würde dieser functionsaufruf Folgendes ergeben:

 argCheck(); >>undefined 0 false null 

wie in unserem Standardarray von Argumentwerten definiert. Folgendes ist jedoch weiterhin möglich:

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

But regretfully not:

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

Which would otherwise be logging:

 >>a 0 false 22 

but that’s in a better world! However – for the original question – the topmost function will do just fine. z.B:

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

ps: sorry for not preserving the types of chosen defaults in my argument inputs while writing them.

In all cases where optionalArg is falsy you will end up with defaultValue.

 function myFunc(requiredArg, optionalArg) { optionalArg = optionalArg || 'defaultValue'; console.log(optionalArg); // Do stuff } myFunc(requiredArg); myFunc(requiredArg, null); myFunc(requiredArg, undefined); myFunc(requiredArg, ""); myFunc(requiredArg, 0); myFunc(requiredArg, false); 

All of the above log defaultValue, because all of 6 are falsy. In case 4, 5, 6 you might not be interested to set optionalArg as defaultValue, but it sets since they are falsy.

I suggest you to use ArgueJS this way:

 function myFunc(){ arguments = __({requiredArg: undefined, optionalArg: [undefined: 'defaultValue'}) //do stuff, using arguments.requiredArg and arguments.optionalArg // to access your arguments } 

You can also replace undefined by the type of the argument you expect to receive, like this:

 function myFunc(){ arguments = __({requiredArg: Number, optionalArg: [String: 'defaultValue'}) //do stuff, using arguments.requiredArg and arguments.optionalArg // to access your arguments } 
 function foo(requiredArg){ if(arguments.length>1) var optionalArg = arguments[1]; }