Gibt es eine bessere Möglichkeit, optionale Funktionsparameter in JavaScript zu erstellen?[Duplikat]

StackOverflow https://stackoverflow.com/questions/148901

  •  02-07-2019
  •  | 
  •  

Frage

Auf diese Frage gibt es hier bereits eine Antwort:

Ich habe optionale Parameter in JavaScript immer so gehandhabt:

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

  // Do stuff
}

Gibt es einen besseren Weg, es zu tun?

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

War es hilfreich?

Lösung

Ihre Logik schlägt fehl, wenn optionalArg übergeben wird, sondern wertet als falsch - versuchen Sie dies als eine Alternative

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

oder eine alternative Idiom:

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

Verwenden Sie je nachdem, was Idiom die Absicht am besten zu Ihnen in Verbindung steht!

Andere Tipps

Im ECMAScript 2015 (aka "ES6"), die Sie als Vorgabewert in der Funktionsdeklaration erklären können:

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

Weitere Informationen über sie in diesem Artikel auf MDN .

Dies ist derzeit nur von Firefox unterstützt, aber als der Standard abgeschlossen ist, Unterstützung erwartet schnell zu verbessern.

EDIT (2019.06.12):

Standardparameter werden jetzt weitgehend von modernen Browsern unterstützt. Alle Versionen von Internet Explorer diese Funktion nicht unterstützen. Allerdings Chrome, Firefox und Rand zur Zeit unterstützen es.

Das finde ich die einfachste, lesbare Weise zu sein:

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

Paul Dixon Antwort (in meiner bescheidenen Meinung nach) weniger lesbar als das, aber es kommt auf Präferenz.

insin Antwort ist viel weiter fortgeschritten, aber viel nützlicher für große Funktionen!

EDIT 2013.11.17 09.33: Ich habe ein Paket für Node.js geschaffen, die es einfacher zu "Überlast" Funktionen (Methoden) genannt parametric .

Wenn Sie in eine wörtliche NULL einzuspannen, dann könnten Sie einige Probleme haben. Abgesehen davon, nein, ich glaube, du bist wahrscheinlich auf dem richtigen Weg.

Die andere Methode einige Leute wählen ist ein assoziatives Array von Variablen nehmen durch die Argumentliste iterieren. Es sieht ein bisschen ordentlicher aber ich glaube, es ist ein wenig (sehr wenig) etwas Prozess / speicherintensiv.

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];

    // ...
}

Im Idealfall würden Sie Refactoring ein Objekt und es mit einem Standard-Objekt verschmelzen, so dass die Reihenfolge in denen Argumente (siehe den zweiten Abschnitt dieser Antwort, unten).

spielt keine Rolle, bestanden

Wenn Sie jedoch nur etwas wollen schnell, zuverlässig, einfach zu bedienen und nicht sperrig, versuchen Sie dies:


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

  • Er skaliert elegant: minimal zusätzlicher Code für jeden neuen Standard
  • Sie können es überall einfügen: nur die Anzahl der erforderlichen Argumente und Variablen ändern
  • Wenn Sie undefined auf ein Argument mit einem Standardwert, auf diese Weise übergeben werden sollen, wird die Variable als undefined gesetzt. Die meisten anderen Optionen auf dieser Seite undefined mit dem Standardwert ersetzen würde.

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

Bereitstellen
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 ähnlich href="https://stackoverflow.com/a/148933/568458"> roenving Antwort mit arguments nicht Function.arguments .


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

Der obige Code, wie viele Möglichkeiten der Standardargumente zu tun, kann nicht Argumente übergibt außer der Reihe, zum Beispiel, vorbei optionalC aber verlassen optionalB auf das Standardzurückzugreifen.

Eine gute Möglichkeit dafür ist, Objekte zu übergeben und mit einem Standard-Objekt verschmelzen. Das ist auch gut für die Wartbarkeit (nur darauf achten, Ihren Code lesbar zu halten, werden so künftig Mitarbeiter über die möglichen Inhalte der Objekte nicht verlassen werden Erraten Sie laufen um).

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

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 einige verschiedene Systeme dafür. Ich habe immer für arguments.length getestet:

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

  ...

- so kann es nicht möglicherweise fehlschlagen, aber ich weiß nicht, ob Sie sich eine Chance zu scheitern hat, gerade jetzt kann ich nicht ein Szenario ausdenken, wo es wäre eigentlich nicht ...

Und dann Paul bereitgestellt einen Fehler Szenario -)

ähnlich wie Oli Antwort, verwende ich ein Argument Objekt und ein Objekt, das den Standardwert definiert. Mit etwas 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 ein bisschen schöner 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 mit dieser Methode ist schön?

  • Sie können so viele Argumente weglassen, wie Sie wollen - wenn Sie den Wert eines Arguments außer Kraft setzen möchten, können Sie einfach dieses Argument liefern, anstatt dass ausdrücklich undefined passieren, wenn, sagen, es gibt fünf Argumente und Sie nur wollen die letzten zu gestalten, wie Sie vorgeschlagen, mit einigen der anderen Methoden zu tun haben würden.
  • Wenn Sie mit einer Konstruktor Funktion für ein Objekt arbeiten, die von einem anderen erbt, ist es einfach, alle Argumente zu akzeptieren, die durch den Konstruktor des Objekts erforderlich ist, von Sie erben, wie Sie diese Argumente nicht nennen müssen in Ihrem Konstruktor Unterschrift oder sogar Ihre eigenen Vorgaben liefern (das Konstruktor übergeordnete Objekts lassen sich das für Sie tun, wie oben zu sehen, wenn CharField ruft Field Konstruktor).
  • Child-Objekte in Vererbungshierarchien Argumente für ihre Mutter Konstruktor anpassen können, wie sie es für richtig, ihre eigenen Standardwerte durchzusetzen oder um sicherzustellen, dass ein bestimmter Wert immer verwendet werden.

Wenn Sie Standardwerte extensiv verwenden, dies scheint viel besser lesbar:

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;
}

Just erklären diese Funktion auf dem globalen eScope.

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

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

* PS können Sie die defaultValue-Funktion auf einen kurzen Namen umbenennen, nur nicht default verwenden, es ist ein reserviertes Wort in Javascript.

Los Art Überprüfung

Einfach zu schreiben, aber 0, '', false, null und undefined werden auf Standardwert umgewandelt werden, das Ergebnis könnte nicht erwartet.

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

strenge Typprüfung

Längerer, sondern deckt Mehrzahl der Fälle. Nur Fall, in dem es Standardwert falsch zuordnet, wenn wir undefined als Parameter übergeben.

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

Überprüfen Argumente Variable

Fängt alle Fälle aber ist die ungeschickte schreiben zu können.

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

ES6

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

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

}

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

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

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

  // do stuff
}

Sie können auch Standardwerte Argumente wie diese verwenden

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

Ich bin ein paar grundlegenden Veränderungen zu sehen, über den Umgang mit optionalen Variablen verwendet. 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 falsy Standard mit variabler a verwendet wird, zum Beispiel verwendet ausgiebig in Backbone.js .

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

_.defaults(optionalArg, 'defaultValue');

auf diese Frage gelandet, die Suche nach Standardparametern in EcmaScript 2015 , also nur zu erwähnen ...

Mit ES6 können wir Standardparameter :

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

doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"

Während eines Projekts ich fest, dass ich wiederhole mich zu viel mit den optionalen Parameter und Einstellungen, so habe ich eine Klasse, die die Typprüfung behandelt und weist einen Standardwert, der in einer ordentlichen und lesbaren Code führt. Siehe Beispiel und lassen Sie mich wissen, ob dies für Sie arbeitet.

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 Klasse:

(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 @ Paul Antwort Downvoted, aber die Validierung gegen null ist eine gute Wahl. Vielleicht wird ein bejahendes Beispiel besser Sinn machen:

In JavaScript ein verpasster Parameter ist wie eine deklarierte Variable, die nicht initialisiert (nur var a1;). Und der Gleichheitsoperator wandelt die undefinierte auf null, so funktioniert dies sehr gut mit beiden Werttypen und Objekten, und das ist, wie Coffeescript optionale Parameter behandelt.

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...';
    //...
}

Obwohl, gibt es Bedenken, dass für die beste Semantik ist typeof variable === 'undefined' ist etwas besser. Ich bin nicht dagegen zu verteidigen, da es die Sache des zugrunde liegenden API ist, wie eine Funktion implementiert ist; es sollte die API Benutzer nicht interessieren.

Ich möchte auch hinzufügen, dass hier ist der einzige Weg, um körperlich sicher jedes Argument zu machen verpasst wurden, die in Operator die leider nicht mit den Parameternamen arbeiten, so haben einen Index des arguments passieren.

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 für undefiniert ist unnötig und ist nicht so robust wie es sein könnte, weil, wie user568458 wies darauf hin, sofern die Lösung, wenn null oder falsch nicht übergeben wird. Benutzer des API könnte denken, falsch oder null würde das Verfahren erzwingen, dass der Parameter zu vermeiden.

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. Stattdessen versuchen:

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

Was ergibt:

defaultValue
provided
defaultValue
defaultValue

Das einzige Szenario, in dem dies nicht optimal ist, wenn Sie optionale Parameter tatsächlich haben die booleans oder vorsätzliche null sein sollen zu.

habe ich versucht, einige Optionen in hier erwähnt und Leistung getestet sie. In diesem Moment scheint die logicalor die schnellsten zu sein. Obwohl dies unterliegt die Veränderung im Laufe der Zeit (verschiedene JavaScript-Engine-Versionen).

Das 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 Performance-Test leicht repliziert werden kann, auf: http://jsperf.com/optional-parameters-typeof-vs-switch/ 2

Dies ist der Code des Tests:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        function TypeofFunction(param1, optParam1, optParam2, optParam3) {
            optParam1 = (typeof optParam1 === "undefined") ? "Some default" : optParam1;
            optParam2 = (typeof optParam2 === "undefined") ? "Another default" : optParam2;
            optParam3 = (typeof optParam3 === "undefined") ? "Some other default" : optParam3;
        }

        function TypeofFunction2(param1, optParam1, optParam2, optParam3) {
            optParam1 = defaultValue(optParam1, "Some default");
            optParam2 = defaultValue(optParam2, "Another default");
            optParam3 = defaultValue(optParam3, "Some other default");
        }

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

        function SwitchFuntion(param1, optParam1, optParam2, optParam3) {
            switch (arguments.length - 1) { // <-- 1 is number of required arguments
                case 0:
                    optParam1 = 'Some default';
                case 1:
                    optParam2 = 'Another default';
                case 2:
                    optParam3 = 'Some other default';
            }
        }

        function ObjectFunction(args) {
            var defaults = {
                optParam1: 'Some default',
                optParam2: 'Another default',
                optParam3: 'Some other default'
            }
            args = $.extend({}, defaults, args);
        }

        function LogicalOrFunction(param1, optParam1, optParam2, optParam3) {
            optParam1 || (optParam1 = 'Some default');
            optParam2 || (optParam1 = 'Another default');
            optParam3 || (optParam1 = 'Some other default');
        }
    };
</script>

Dies ist, was ich am Ende mit:

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 ...
}

wie folgt aufgerufen:

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

Leute -

bei dieser und anderen Lösungen Nach einem Blick, habe ich versucht, eine Reihe von ihnen aus einem Code-Snippet mit ursprünglich von W3Schools als Basis. Sie können finden, was in der folgenden funktioniert. Jeder des Artikels kommentierte Arbeiten als gut und ist auf diese Weise Sie zu erlauben, einfach zu experimentieren, indem einzelne Kommentare zu entfernen. Um klar zu sein, es ist die „eyecolor“ Parameter, der nicht definiert ist.

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.<br/>" +
              "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. Mit diesem können Sie einen beliebigen Parameter verlassen Sie wollen. Die Reihenfolge des optionalen Parameters 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'
        });
  1. arg || 'default' ist eine großartige Art und Weise und arbeitet für 90% der Fälle

  2. Es schlägt fehl, wenn Sie Werte müssen übergeben, die möglicherweise ‚falsy‘

    • false
    • 0
    • NaN
    • ""

    Für diese Fälle müssen Sie etwas ausführlicher und prüfen, ob undefined sein

  3. Seien Sie auch vorsichtig sein, wenn Sie erste optionale Argumente haben, müssen Sie die Arten von all Ihre Argumente bewusst sein,

In allen Fällen, in denen optionalArg ist falsy Sie mit default enden wird.

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

Alle der oben default einzuloggen, weil alle 6 falsy sind. Für den Fall, 4, 5, 6 könnten Sie nicht interessiert sein optionalArg als default zu setzen, aber es setzt, da sie falsy sind.

korrigiert mich wenn ich falsch liege, aber dies scheint, wie die einfachste Art und Weise (für ein Argument jedenfalls):

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

Diejenigen Haushalte sind kürzer als die typeof Operator Version.

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

Ich schlage vor, Sie verwenden ArgueJS diese Weise:

function myFunc(){
  arguments = __({requiredArg: undefined, optionalArg: [undefined: 'defaultValue'})

  //do stuff, using arguments.requiredArg and arguments.optionalArg
  //    to access your arguments

}

Sie können auch undefined durch die Art des Arguments ersetzen Sie erhalten erwarten, wie folgt aus:

function myFunc(){
  arguments = __({requiredArg: Number, optionalArg: [String: 'defaultValue'})

  //do stuff, using arguments.requiredArg and arguments.optionalArg
  //    to access your arguments

}

Es scheint, dass der sicherste Weg darin besteht, mit allem und jedem umzugehen falsche Typen geliefert Argumente bevor Sie sich für die Verwendung entscheiden Standard - dient dazu, die Existenz\Präsenz des zu überprüfen optionales Argument in der aufgerufenen Funktion.

Indem wir uns auf die Erstellung von Argumentobjektmitgliedern verlassen, die nicht einmal erstellt werden, wenn das Argument fehlt, unabhängig davon, ob es deklariert ist, können wir Ihre Funktion wie folgt schreiben:

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

Ausnutzen dieses Verhaltens:Wir können sicher und willkürlich und explizit nach fehlenden Werten in der Argumentliste suchen, wenn wir sicherstellen müssen, dass die Funktion einen bestimmten, in ihrer Prozedur erforderlichen Wert erhält.

Im folgenden Democode werden wir bewusst ein typlos Und wertlos nicht definiert als Standardwert, um bestimmen zu können, ob es bei falschen Argumentwerten wie 0 false usw. fehlschlagen könnte 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 ) 
}

Überprüfen Sie nun einige falsche Argumentwerte, um zu sehen, ob ihr Vorhandensein korrekt erkannt und daher ausgewertet wird WAHR:

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

Das bedeutet, dass die Erkennung der erwarteten Argumentwerte nicht fehlgeschlagen ist.Hier haben wir eine Prüfung mit fehlenden Argumenten, die laut unserem Algorithmus ihre Standardwerte annehmen sollten, auch wenn dies der Fall wäre falsch.

argCheck( );
>> undefined false 0 null

Wie wir sehen können, die Argumente arg1, arg2, arg3 und das Unerklärte arg4, geben ihre genaue Antwort zurück Standard Werte, wie bestellt.Da wir nun sichergestellt haben, dass es funktioniert, können wir die Funktion, die sie tatsächlich verwenden kann, wie im ersten Beispiel umschreiben, indem wir Folgendes verwenden:entweder Wenn oder ein ternär Zustand.

Bei Funktionen, die mehr als ein optionales Argument haben, hätte uns eine Schleife möglicherweise einiges erspart.Aber da Streit Namen werden nicht initialisiert, wenn ihre Werte nicht bereitgestellt werden. Wir können nicht mehr über Namen auf sie zugreifen, selbst wenn wir programmgesteuert einen Standardwert geschrieben haben, sondern nur über Argumente[Index] Was für die Lesbarkeit des Codes nutzlos ist.

Aber abgesehen von dieser Unannehmlichkeit, die in bestimmten Codierungssituationen völlig akzeptabel sein könnte, gibt es ein weiteres unberücksichtigtes Problem für mehrere und beliebig viele Argumentstandards.Dies kann und sollte als Fehler betrachtet werden, da wir Argumente nicht mehr überspringen können, wie wir es früher vielleicht hätten tun können, ohne einen Wert anzugeben, in einer Syntax wie:

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

denn es wird werfen!Das macht es für uns unmöglich, unser Argument durch ein bestimmtes zu ersetzen falsch Typ unseres gewünschten Standardwerts.Was dumm ist, denn das Argumente Objekt ist ein Array-ähnliches Objekt und soll diese Syntax und Konvention unverändert unterstützen, nativ oder standardmäßig!

Aufgrund dieser kurzsichtigen Entscheidung können wir nicht länger 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 Argumentzeile schreiben und zumindest über args.index auf sie zugreifen.

Dieser Funktionsaufruf würde beispielsweise 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

Aber leider nicht:

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

Was sonst protokolliert würde:

>>a 0 false 22

aber das ist in einer besseren Welt!Für die ursprüngliche Frage reicht jedoch die oberste Funktion vollkommen aus.z.B.:

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

p.s.:Entschuldigung, dass ich das nicht erhalten habe Typen der gewählten Standardwerte in meinen Argumenteingaben beim Schreiben.

function foo(requiredArg){
  if(arguments.length>1) var optionalArg = arguments[1];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top