Existe-t-il un meilleur moyen de définir des paramètres de fonction facultatifs en JavaScript? [dupliquer]

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

  •  02-07-2019
  •  | 
  •  

Question

    

Cette question a déjà une réponse ici:

         

J'ai toujours géré les paramètres facultatifs en JavaScript comme ceci:

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

  // Do stuff
}

Y a-t-il une meilleure façon de le faire?

Existe-t-il des cas où l'utilisation de || comme celui-ci échouera?

Était-ce utile?

La solution

Votre logique échoue si optionalArg est passé, mais est évaluée comme fausse - essayez ceci comme alternative

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

Ou un autre langage:

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

Utilisez l’idiome qui vous communique le mieux l’intention!

Autres conseils

Dans ECMAScript 2015 (ou "ES6"), vous pouvez déclarer les valeurs d'argument par défaut dans la déclaration de fonction:

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

Pour en savoir plus à leur sujet, cet article sur MDN .

C’est actuellement uniquement pris en charge par Firefox , mais comme la norme est terminée, le support devrait s’améliorer rapidement.

MODIFIER (2019-06-12):

Les paramètres par défaut sont maintenant largement pris en charge par les navigateurs modernes. Toutes les versions d'Internet Explorer ne prennent pas en charge cette fonctionnalité. Cependant, Chrome, Firefox et Edge le prennent actuellement en charge.

Je trouve que c'est la manière la plus simple et la plus lisible:

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

La réponse de Paul Dixon (à mon humble avis) est moins lisible que cela, mais elle se résume à une préférence.

La réponse de

insin est beaucoup plus avancée, mais beaucoup plus utile pour les grandes fonctions!

EDIT 17/11/2013 21:33: j'ai créé un package pour Node.js qui facilite la "surcharge". fonctions (méthodes) appelées paramétrique .

Si vous devez insérer un NULL littéral, vous risquez d'avoir quelques problèmes. En dehors de cela, non, je pense que vous êtes probablement sur la bonne voie.

L’autre méthode choisie par certaines personnes consiste à utiliser un tableau assoc de variables itérant dans la liste des arguments. Cela semble un peu plus ordonné, mais j’imagine que c’est un peu (très peu) plus intensif en mémoire / processus.

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

    // ...
}

Idéalement, vous refactorisez pour passer un objet et le le fusionner avec un objet par défaut, de sorte que la commande dans lequel les arguments sont passés importe peu (voir la deuxième section de cette réponse, ci-dessous).

Si vous souhaitez simplement quelque chose de rapide, fiable, facile à utiliser et peu encombrant, essayez ceci:

Un correctif rapide pour tout nombre d'arguments par défaut

  • Il évolue avec élégance: code supplémentaire minimal pour chaque nouvelle valeur par défaut
  • Vous pouvez le coller n'importe où: changez simplement le nombre d'arguments et de variables requis
  • Si vous voulez passer undefined à un argument avec une valeur par défaut, la variable est ainsi définie comme undefined . La plupart des autres options de cette page remplaceraient undefined par la valeur par défaut.

Voici un exemple pour fournir des valeurs par défaut pour trois arguments facultatifs (avec deux arguments obligatoires)

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
  }

}

Une simple démo . Ceci est similaire à la réponse de roenving , mais facilement extensible pour un nombre quelconque d'arguments par défaut, plus facile à mettre à jour et en utilisant arguments et non Function.arguments .

Passage et fusion d'objets pour plus de flexibilité

Le code ci-dessus, comme de nombreuses manières de faire des arguments par défaut, ne peut pas passer les arguments hors séquence, par exemple, en passant optionalC tout en laissant optionalB pour revenir à son défaut.

Une bonne option consiste à transmettre des objets et à les fusionner avec un objet par défaut. C’est également bon pour la facilité de maintenance (veillez à ce que votre code reste lisible afin que les futurs collaborateurs ne soient plus laissés au hasard quant au contenu possible des objets que vous transmettez).

Exemple d'utilisation de jQuery. Si vous n'utilisez pas jQuery, vous pouvez utiliser le _. Defaults (object, default) de Underscore ou parcourir ces options :

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

Voici un exemple simple d'utilisation .

Vous pouvez utiliser différents schémas pour cela. J'ai toujours testé les arguments.length:

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

  ...

- cela ne peut donc pas échouer, mais je ne sais pas si votre chemin a des chances d’échouer. Pour l’instant, je ne peux pas imaginer un scénario où il échouerait en fait ...

Ensuite, Paul a fourni un scénario qui échoue! -)

Semblable à la réponse de Oli, j'utilise un argument Object et un objet qui définit les valeurs par défaut. Avec un peu de sucre ...

/**
 * 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
}

... cela peut être un peu plus agréable.

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)

En quoi cette méthode est-elle intéressante?

  • Vous pouvez omettre autant d'arguments que vous le souhaitez - si vous souhaitez uniquement remplacer la valeur d'un argument, vous pouvez simplement fournir cet argument au lieu de devoir explicitement passer undefined lorsque, par exemple, Il y a 5 arguments et vous ne souhaitez personnaliser que le dernier, comme vous le feriez avec certaines des autres méthodes suggérées.
  • Lorsque vous travaillez avec une fonction constructeur pour un objet qui hérite d'un autre, il est facile d'accepter tous les arguments requis par le constructeur de l'objet dont vous héritez, car vous n'avez pas à les nommer dans votre signature du constructeur, ou même fournir vos propres valeurs par défaut (laissez le constructeur de l’objet parent le faire pour vous, comme indiqué ci-dessus lorsque CharField appelle le constructeur de Field ).
  • Les objets enfants dans les hiérarchies d'héritage peuvent personnaliser les arguments de leur constructeur parent comme bon leur semble, en appliquant leurs propres valeurs par défaut ou en s'assurant qu'une toujours sera toujours utilisée.

Si vous utilisez beaucoup les valeurs par défaut, cela semble beaucoup plus lisible:

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

Il suffit de déclarer cette fonction sur l'escope global.

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

Modèle d'utilisation fruit = defaultValue (fruit, 'Apple');

* PS, vous pouvez renommer la fonction defaultValue en un nom abrégé. N'utilisez pas default , il s'agit d'un mot réservé en javascript.

Vérification de type en vrac

Facile à écrire, mais 0 , '' , false , null et undefined sera converti en valeur par défaut, ce qui pourrait ne pas être le résultat attendu.

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

Vérification de type stricte

Plus long, mais couvre la majorité des cas. Le seul cas où il attribue incorrectement la valeur par défaut est lorsque nous passons undefined en paramètre.

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

Vérification de la variable d'arguments

Attrape tous les cas, mais est le plus maladroit à écrire.

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

ES6

Malheureusement, le support de navigateur est très médiocre pour le moment

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

}

Avec ES2015 / ES6, vous pouvez tirer parti de Object.assign , qui peut remplacer $. extend () ou _. defaults ()

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

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

  // do stuff
}

Vous pouvez également utiliser des arguments par défaut comme celui-ci

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

Je suis habitué à voir quelques variations de base sur la gestion des variables optionnelles. Parfois, les versions assouplies sont utiles.

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

La valeur par défaut utilisée avec la variable a est, par exemple, utilisée de manière intensive dans Backbone.js .

Si vous utilisez la bibliothèque Underscore (vous devriez, c'est une bibliothèque géniale):

_.defaults(optionalArg, 'defaultValue');

Atteint cette question en recherchant les paramètres par défaut dans EcmaScript 2015 , mentionnant donc simplement ...

Avec ES6 , vous pouvez paramètres par défaut :

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

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

Au cours d’un projet, j’ai remarqué que je me répétais trop avec les paramètres et paramètres facultatifs; j’ai donc créé une classe qui gère le contrôle de type et attribue une valeur par défaut qui donne un code net et lisible. Voir exemple et laissez-moi savoir si cela fonctionne pour vous.

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 : [];
}

Utilisation de cette classe:

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

Je ne sais pas pourquoi la réponse de @Paul est rejetée, mais la validation par rapport à null est un bon choix. Peut-être qu'un exemple plus affirmatif aura plus de sens:

En JavaScript, un paramètre manquant est semblable à une variable déclarée non initialisée (juste var a1; ). Et l'opérateur d'égalité convertit l'indéfini en null. Cela fonctionne donc très bien avec les types de valeur et les objets. C'est ainsi que CoffeeScript gère les paramètres facultatifs.

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

Cependant, il est à craindre que typeof variable === 'undefined' soit légèrement meilleur pour la meilleure sémantique. Je ne suis pas sur le point de défendre cela puisqu'il s'agit de l'API sous-jacente de la manière dont une fonction est implémentée; cela ne devrait pas intéresser l'utilisateur de l'API.

Je devrais également ajouter que voici le seul moyen de s’assurer physiquement de n’importe quel argument, en utilisant l’opérateur dans qui ne fonctionnera malheureusement pas avec les noms de paramètres; il faut donc passer un index du 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);

Le test pour non défini est inutile et n’est pas aussi robuste qu’il pourrait être car, comme l’a souligné utilisateur568458, la solution fournie échouait si la valeur null ou la valeur false était transmise. Les utilisateurs de votre API peuvent penser que false ou null forceront la méthode à éviter ce paramètre.

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

Le résultat est:

defaultValue
provided
null
false

Ces deux derniers sont potentiellement mauvais. Au lieu d'essayer:

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

Ce qui entraîne:

defaultValue
provided
defaultValue
defaultValue

Le seul scénario qui ne soit pas optimal est celui où vous avez en réalité des paramètres facultatifs destinés à être des booléens ou des valeurs nulles intentionnelles.

J'ai essayé certaines des options mentionnées ici et les ai testées. En ce moment, le logique semble être le plus rapide. Bien que cela soit sujet à des changements dans le temps (différentes versions du moteur JavaScript).

Voici mes résultats (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

Ce test de performance peut être facilement répliqué sur: http://jsperf.com/optional-parameters-typeof-vs-switch/ 2

Ceci est le code du test:

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

Voici ce avec quoi j'ai fini:

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

Appelé comme ceci:

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

Les gens -

Après avoir examiné ces solutions, parmi d’autres, j’en ai essayé un certain nombre en utilisant comme base un extrait de code provenant de W3Schools. Vous pouvez trouver ce qui fonctionne dans ce qui suit. Chacun des éléments commentés fonctionne également et vous permet d'expérimenter simplement en supprimant des commentaires individuels. Pour être clair, il s'agit de la "couleur oculaire". paramètre qui n'est pas défini.

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/

Voici ma solution. Avec cela, vous pouvez laisser n'importe quel paramètre que vous voulez. L'ordre des paramètres facultatifs n'est pas important et vous pouvez ajouter une validation personnalisée.

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' est un excellent moyen et fonctionne dans 90% des cas

  2. Il échoue lorsque vous devez transmettre des valeurs pouvant être "fausses"

    • false
    • 0
    • NaN
    • ""

    Dans ces cas, vous devrez être un peu plus bavard et vérifier si undefined

  3. Faites également attention lorsque vous avez d'abord des arguments facultatifs, vous devez connaître les types de tous vos arguments

Dans tous les cas où optionalArg est faux, vous obtiendrez 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);

Toutes les valeurs de journal ci-dessus, defaultValue, car toutes les 6 sont faussaires. Dans les cas 4, 5 et 6, vous ne souhaiterez peut-être pas définir facultatifArg avec defaultValue, mais cette option est définie car elles sont faussées.

Corrigez-moi si je me trompe, mais cela semble être le moyen le plus simple (pour un argument, en tout cas):

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

Celles-ci sont plus courtes que la version de l'opérateur typeof.

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

Je vous suggère d'utiliser ArgueJS de cette manière:

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

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

}

Vous pouvez également remplacer undefined par le type de l'argument que vous souhaitez recevoir, comme ceci:

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

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

}

Il semble que le moyen le plus sûr - de traiter tous les \ any types de fausseté des arguments fournis avant de décider d'utiliser le default - vérifie l'existence \ présence de l'argument facultatif dans la fonction invoquée.

En vous basant sur la création d'un membre d'objet arguments qui n'est même pas créé si l'argument est manquant, même s'il peut être déclaré, nous pouvons écrire votre fonction de la manière suivante:

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

En utilisant ce comportement: Nous pouvons vérifier en toute sécurité les valeurs manquantes sur la liste des arguments de manière arbitraire et explicite chaque fois que nous devons nous assurer que la fonction obtient une certaine valeur requise dans sa procédure.

Dans le code de démonstration suivant, nous allons délibérément placer sans type et sans valeur undefined en tant que valeur par défaut être en mesure de déterminer s’il peut échouer avec des valeurs d’argument faussées, telles que 0 faux, etc., ou s’il se comporte comme prévu.

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

Maintenant, vérifions quelques valeurs-arguments faussement fausses pour voir si leur présence est correctement détectée et donc évaluée à vrai :

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

Ce qui signifie -ils n'ont pas échoué à la reconnaissance de / comme valeurs d'argument attendues. Nous avons ici une vérification avec tous les arguments manquants, lesquels, selon notre algo, devraient acquérir leurs valeurs par défaut, même s'ils sont falsy .

argCheck( );
>> undefined false 0 null

Comme nous pouvons le constater, les arguments arg1, arg2, arg3 et le non déclaré arg4 renvoient leur exact défaut valeurs, comme ordonné. Puisque nous nous sommes assurés que cela fonctionne, nous pouvons réécrire la fonction qui pourra en réalité les utiliser comme dans le premier exemple en utilisant: if ou un condition ternaire .

Sur les fonctions qui ont plus d’un argument optionnel, un passage en boucle aurait pu nous sauver quelques bits. Mais comme les arguments noms ne sont pas initialisés si leurs valeurs ne sont pas fournies, nous ne pouvons plus y accéder par noms même si nous avons écrit par programme une valeur par défaut, nous pouvons n'y accédez que par arguments [index] qui rendent la lecture de code inutile sage.

Mais en dehors de cet inconvénient, qui dans certaines situations de codage peut être totalement acceptable, il existe un autre problème non comptabilisé pour le nombre d'arbitres par défaut multiples et arbitraires. Ce qui peut et devrait être considéré comme un bogue, car nous ne pouvons plus ignorer les arguments, comme nous aurions pu le faire une fois, sans donner de valeur, dans une syntaxe telle que:

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

car il va lancer! Ce qui nous empêche de substituer notre argument à un type spécifique falsy de la valeur par défaut souhaitée. Ce qui est stupide, car l’objet arguments est un objet semblable à un tableau et devrait prendre en charge cette syntaxe et cette convention telles quelles, nativement ou par défaut!

En raison de cette décision à courte vue, nous ne pouvons plus espérer écrire une fonction comme celle-ci:

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

auquel cas, nous pourrions écrire chaque valeur par défaut d'un type souhaité dans la ligne d'arguments et pouvoir au moins y accéder par args.index.

Par exemple, cet appel de fonction donnerait:

argCheck();
>>undefined 0 false null

tel que défini dans notre tableau d'arguments par défaut. Cependant, les possibilités suivantes sont toujours possibles:

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

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

Mais malheureusement pas:

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

Qui se connecterait autrement:

>>a 0 false 22

mais c'est dans un monde meilleur! Cependant - pour la question initiale - la fonction la plus haute ira très bien. par exemple:

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

p.s .: Désolé de ne pas conserver les types des valeurs par défaut choisies dans mes entrées d'argument lors de leur écriture.

function foo(requiredArg){
  if(arguments.length>1) var optionalArg = arguments[1];
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top