Finnes det en bedre måte å gjøre valgfunksjonsparametre i Javascript?

stemmer
759

Jeg har alltid håndtert valgfrie parametere i Javascript som dette:

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

  // Do stuff
}

Finnes det en bedre måte å gjøre det?

Er det noen tilfeller der bruker ||som som kommer til å mislykkes?

Publisert på 29/09/2008 klokken 14:27
kilden bruker
På andre språk...                            


29 svar

stemmer
1k

Din logikk mislykkes hvis optionalArg er passert, men evalueres som falsk - prøve dette som et alternativ

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

Eller et alternativ idiom:

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

Bruk den formspråk kommuniserer hensikten beste for deg!

Svarte 29/09/2008 kl. 14:30
kilden bruker

stemmer
17

Du kan bruke noen ulike ordninger for det. Jeg har alltid testet for arguments.length:

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

  ...

- Dermed kan det umulig å mislykkes, men jeg vet ikke om veien har noen sjanse for å mislykkes, akkurat nå kan jeg ikke tenke seg et scenario hvor det faktisk ville mislykkes ...

Og da Paul gitt en sviktende scenario -!)

Svarte 29/09/2008 kl. 14:33
kilden bruker

stemmer
44

Hvis du trenger å kaste en bokstavelig NULLi, så kan du ha noen problemer. Bortsett fra det, nei, jeg tror du er sannsynligvis på rett spor.

Den andre metoden noen mennesker velger tar en tilkn rekke variabler gjentakelse gjennom en argumentlisten. Det ser litt penere, men jeg antar det er en liten (veldig liten) litt mer prosess / minne intensive.

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

    // ...
}
Svarte 29/09/2008 kl. 14:34
kilden bruker

stemmer
13

I likhet med Oli svar, jeg bruker et argument objekt og et objekt som definerer standardverdiene. Med litt sukker ...

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

... dette kan gjøres litt bedre.

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)

Hva er fint om denne metoden?

  • Du kan utelate så mange argumenter som du vil - hvis du bare ønsker å overstyre verdien av ett argument, kan du bare gi det argumentet, i stedet for å måtte eksplisitt passere undefinednår, sier det er 5 argumenter og du bare ønsker å tilpasse den siste en, som du ville ha å gjøre med noen av de andre metodene foreslått.
  • Når du arbeider med en konstruktør funksjon for et objekt som arver fra en annen, er det lett å akseptere noen argumenter som kreves av konstruktøren av objektet du arver fra, så du trenger ikke å nevne disse argumentene i din konstruktør signatur, eller selv gi dine egne mislighold (la foreldrene Object konstruktør gjøre det for deg, sett ovenfra når CharFieldsamtalene Fieldskjer konstruktør).
  • Ordnede objekter i arv hierarkier kan tilpasse argumenter for deres foreldre konstruktør som de ønsker, å håndheve sine egne standardverdier eller at en viss verdi vil alltid bli brukt.
Svarte 29/09/2008 kl. 23:16
kilden bruker

stemmer
125

Jeg synes dette å være den enkleste, mest lesbar måte:

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

Paul Dixon svar (i min ydmyke mening) er mindre lesbar enn dette, men det kommer ned til preferanse.

insin svar er mye mer avansert, men mye mer nyttig for store funksjoner!

EDIT 11/17/2013 21:33: Jeg har laget en pakke for node.js som gjør det lettere å "overload" funksjoner (metoder) kalt parametrisk .

Svarte 14/11/2011 kl. 21:23
kilden bruker

stemmer
32

Ideelt sett ville du refactor å passere et objekt og fusjonere det med en standard objekt, så i hvilken rekkefølge argumentene er gått spiller ingen rolle (se den andre delen av dette svaret, nedenfor).

Hvis imidlertid du bare vil ha noe rask, pålitelig, enkel å bruke og ikke klumpete, prøv dette:


En ren rask løsning for en rekke standardargumenter

  • Den skalerer elegant: minimal ekstra kode for hver ny standard
  • Du kan lime den hvor som helst: bare endre antall nødvendige args og variabler
  • Hvis du ønsker å sende undefinedtil en krangel med en standardverdi, på denne måten, er variabelen satt som undefined. De fleste andre alternativer på denne siden ville erstatte undefinedmed standardverdien.

Her er et eksempel for å gi standardverdier for tre valgfrie argumenter (med to nødvendige argumenter)

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
  }

}

Enkel demo . Dette ligner på roenving svar , men lett utbyggbar for en rekke standard argumenter, enklere å oppdatere, og ved hjelp av argumentsikkeFunction.arguments .


Passerer og sammenslåing objekter for mer fleksibilitet

Koden ovenfor, i likhet med mange måter å gjøre standard argumenter, kan ikke passere argumenter ut av sekvensen, for eksempel, passerer optionalCmen forlater optionalBå falle tilbake til standard.

Et godt alternativ til det er å passere gjenstander og fusjonere med et standardobjekt. Dette er også bra for vedlikeholdbarhet (bare passe på å holde koden lesbar, slik at fremtidige samarbeidspartnere vil ikke bli igjen å gjette om mulige innholdet i gjenstander du passerer rundt).

Eksempel anvendelse av jQuery. Hvis du ikke bruker jQuery, kan du i stedet bruke Underscore er _.defaults(object, defaults)eller bla gjennom disse alternativene :

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

Her er et enkelt eksempel på den i aksjon .

Svarte 20/02/2012 kl. 15:36
kilden bruker

stemmer
8

Hvis du bruker standardinnstillingene mye, virker dette mye mer 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;
}

Bare erklære denne funksjonen på den globale escope.

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

bruksmønster fruit = defaultValue(fruit,'Apple');

* PS du kan endre navn på defaultValuefunksjonen til et kort navn, bare ikke bruke defaultdet er et reservert ord i Javascript.

Svarte 15/05/2012 kl. 21:23
kilden bruker

stemmer
121

I ECMAScript 2015 (aka "ES6") kan du erklære standardargumentverdier i funksjonen erklæring:

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

Mer om dem i denne artikkelen på MDN (til tross artikkelen tittelen, de er kalt "argumenter", ikke "parametre," i Javascript).

Dette er foreløpig bare støttes av Firefox , men som standard er fullført, forventer støtte til å forbedre seg raskt.

Svarte 19/02/2013 kl. 13:13
kilden bruker

stemmer
0

Korriger meg hvis jeg tar feil, men dette virker som den enkleste måten (for ett argument, uansett):

function myFunction(Required,Optional)
{
    if (arguments.length<2) Optional = "Default";
    //Your code
}
Svarte 21/02/2013 kl. 02:03
kilden bruker

stemmer
-1

Jeg foreslår at du bruker ArgueJS på denne måten:

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

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

}

Du kan også erstatte undefinedav type argumentet du forvente å motta, som dette:

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

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

}
Svarte 12/04/2013 kl. 15:35
kilden bruker

stemmer
2

Jeg vet ikke hvorfor @ Paulus 'svar er downvoted, men validering mot nuller et godt valg. Kanskje en mer bekreftende eksempel vil gjøre bedre følelse:

I Java en savnet parameter er som en erklært variabel som ikke er initialisert (bare var a1;). Og likestilling operatør konverterer udefinert til null, så dette fungerer bra med både verdityper og objekter, og dette er hvordan CoffeeScript håndterer valgfrie parametere.

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

Skjønt, det er bekymring for at de beste semantikk er typeof variable === 'undefined'er litt bedre. Jeg er ikke i ferd med å forsvare dette siden det er saken av den underliggende API hvordan en funksjon er implementert; det bør ikke interesserer API bruker.

Jeg bør også legge til at her er den eneste måten å fysisk være sikker på noe argument var savnet, ved hjelp av inoperatøren som dessverre ikke vil fungere med parameternavnene så må passere en indeks over 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);
Svarte 07/05/2013 kl. 13:31
kilden bruker

stemmer
2

Testen for udefinert er unødvendig og er ikke like robust som det kunne være fordi, som user568458 påpekt, mislykkes løsningen gitt hvis null eller usant er passert. Brukere av API din kanskje tror falsk eller null ville tvinge metoden for å unngå denne parameteren.

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

Resultatet er:

defaultValue
provided
null
false

De to siste er potensielt dårlig. I stedet prøve:

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

Noe som resulterer i:

defaultValue
provided
defaultValue
defaultValue

Den eneste scenario der dette ikke er optimalt er når du faktisk har valgfrie parametere som er ment å være booleans eller tilsiktet null.

Svarte 27/09/2013 kl. 05:15
kilden bruker

stemmer
0

De som er kortere enn typeof operatør versjon.

function foo(a, b) {
    a !== undefined || (a = 'defaultA');
    if(b === undefined) b = 'defaultB';
    ...
}
Svarte 07/11/2013 kl. 18:05
kilden bruker

stemmer
1

Dette er hva jeg endte opp med:

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

Kalt som dette:

WhoLikesCake({ b : "I do" });
Svarte 29/11/2013 kl. 21:04
kilden bruker

stemmer
3

Jeg er vant til å se noen grunnleggende variasjoner på håndtering av valg variabler. Noen ganger, avslappet versjonene er nyttige.

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

Den falsy standard brukes med variabel aer, for eksempel, brukes mye i Backbone.js .

Svarte 13/03/2014 kl. 06:27
kilden bruker

stemmer
-2

Noen kode IntelliSense verktøy, spesielt WebStorm IDE og kanskje jshint, gi advarsler når du kaller en funksjon med færre argumenter enn erklærte:

function foo(a, b) {
    if (typeof b === 'undefined') {
        b = 5;
    }
}

foo(1); /* Warning */

Du kan i stedet gjøre:

function foo(a /*, b */) {
    var b = arguments.length > 1 ? arguments[1] : 2;
}

foo(1);

Merk at bargumentet er deklarert i en kommentar til klarhet.

Svarte 02/04/2014 kl. 15:32
kilden bruker

stemmer
-2
function foo(requiredArg){
  if(arguments.length>1) var optionalArg = arguments[1];
}
Svarte 09/04/2014 kl. 02:03
kilden bruker

stemmer
1

Folkens -

Etter å se på disse og andre løsninger, jeg prøvde en rekke av dem ut med en kodebit opprinnelig fra W3Schools som base. Du kan finne ut hva som fungerer i det følgende. Hvert av elementene kommen arbeid også, og er på den måten slik at du kan eksperimentere ved å fjerne enkeltkommentarer. For å være klar, er det "Eyecolor" parameter som ikke blir definert.

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."; 
Svarte 13/04/2014 kl. 20:53
kilden bruker

stemmer
2

Jeg prøvde noen alternativer som er nevnt her og ytelse testet dem. På dette tidspunktet er logicalor synes å være den raskeste. Selv om dette er gjenstand for endring over tid (forskjellige Javascript-motor versjoner).

Dette er resultatene mine (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

Denne ytelsestest kan enkelt kopieres på: http://jsperf.com/optional-parameters-typeof-vs-switch/2

Dette er koden til 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>
Svarte 19/06/2014 kl. 11:25
kilden bruker

stemmer
3

Hvis du bruker Underscore bibliotek (du skal, er det en fantastisk bibliotek):

_.defaults(optionalArg, 'defaultValue');
Svarte 22/09/2014 kl. 23:59
kilden bruker

stemmer
1
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/

Svarte 03/10/2014 kl. 09:28
kilden bruker

stemmer
8

Loose typesjekking

Lett å skrive, men 0, '', false, nullog undefinedvil bli konvertert til standardverdi, som ikke kan forventes utfallet.

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

Streng typesjekking

Lenger, men dekker fleste tilfeller. Eneste tilfellet hvor det feil tildeler standardverdien er når vi passerer undefinedsom parameter.

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

Kontrollere argumenter variabel

Fanger alle tilfeller, men er den mest klønete å skrive.

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

ES6

Dessverre har dette svært dårlig nettleser støtter i øyeblikket

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

}
Svarte 15/05/2015 kl. 13:46
kilden bruker

stemmer
2

Landet på dette spørsmålet, søker etter standardparametere i ECMAScript 2015 , og dermed bare å nevne ...

Med ES6 kan vi gjøre standardparametere :

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

doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"
Svarte 09/10/2015 kl. 14:19
kilden bruker

stemmer
5

Med ES2015 / ES6 kan du dra nytte av Object.assignnoe som kan erstatte $.extend()eller_.defaults()

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

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

  // do stuff
}

Du kan også bruke standardverdier argumenter som dette

function myFunc(requiredArg, { message: 'Hello', color: 'red', importance: 1 } = {}) {
  // do stuff
}
Svarte 01/02/2016 kl. 11:09
kilden bruker

stemmer
2

Under et prosjekt jeg merket jeg var gjenta meg selv for mye med valgfrie parametere og innstillinger, så jeg gjorde en klasse som håndterer den type kontroll og tildeler en standardverdi som resulterer i ryddig og lesbar kode. Se eksempel og gi meg beskjed hvis dette fungerer for deg.

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

Ved hjelp av denne klassen:

(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));
Svarte 23/03/2016 kl. 10:52
kilden bruker

stemmer
1

Her er min løsning. Med denne kan du la noen parameter du ønsker. Rekkefølgen av de valgfrie parametere er ikke viktig, og du kan legge til tilpassede validering.

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'
        });
Svarte 11/04/2016 kl. 13:51
kilden bruker

stemmer
1
  1. arg || 'default' er en fin måte og arbeider i 90% av tilfellene

  2. Det svikter når du trenger å sende verdier som kan være 'falsy'

    • false
    • 0
    • NaN
    • ""

    For disse tilfellene må du være litt mer utførlig og se etter undefined

  3. Vær også forsiktig når du har valgfrie argumenter først, må du være klar over hvilke typer alle dine argumenter

Svarte 30/04/2016 kl. 19:36
kilden bruker

stemmer
0

I alle tilfeller der optionalArg er falsy du vil ende opp med Default.

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 de ovennevnte logge Default, fordi alle seks er falsy. I tilfellet 4, 5, 6 kan du ikke være interessert i å sette optionalArg som Default, men det setter siden de er falsy.

Svarte 02/09/2016 kl. 04:16
kilden bruker

stemmer
0

Det virker som den sikreste måten - å forholde seg til alle \ eventuelle falsy typer av medfølgende argumenter før de bestemmer seg for å bruke standard - er å sjekke for eksistensen \ nærvær av valgfritt argument i påkalte funksjon.

Stole på argumentene objektet medlem etableringen som ikke selv bli opprettet om argumentet mangler, uavhengig av det faktum at det kan bli erklært, kan vi skrive din funksjon som dette:

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

Utnytte dette problemet: Vi kan trygt sjekke for eventuelle manglende verdier på argumenter liste vilkårlig og tydelig når vi må sørge for at funksjonen får en viss verdi som kreves i sin prosedyre.

I det følgende demo kode vil vi bevisst sette en typeless og verdiløs udefinert som en standardverdi for å kunne avgjøre om det kan mislykkes på falsy argumentverdier, for eksempel 0 false etc., eller hvis den oppfører seg som forventet.

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

Nå sjekker noen falsy argument-verdier for å se om deres tilstedeværelse er riktig registrert og derfor evalueres til sann :

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

Hvilket betyr -de ikke mislykkes anerkjennelse av / som forventet argumentverdier. Her har vi en sjekk med alle argumenter mangler, som ifølge vår algo skal ha standardverdiene, selv om de er falsy .

argCheck( );
>> undefined false 0 null

Som vi kan se, argumenter arg1, arg2, arg3 og svart ARG4 , er tilbake deres eksakte standardverdiene, som bestilt. Fordi vi har nå sørget for at det fungerer, kan vi omskrive funksjon som faktisk vil være i stand til å bruke dem som i første eksempel ved å bruke: enten hvis eller en trefoldig tilstand.

På funksjoner som har mer enn ett valgfritt argument, - en sløyfe gjennom, kan ha reddet oss noen biter. Men siden argument navnene ikke blir initialisert hvis deres verdier ikke blir levert, kan vi ikke tilgang til dem ved navn lenger selv om vi har programma skrevet en standardverdi, kan vi bare få tilgang til dem ved å argumenter [index] som ubrukelig kode lesbarhet klok.

Men bortsett fra det inntrufne, som i visse koding situasjoner kan være helt akseptabelt, det er en annen uforklart problem for flere og vilkårlig antall argument mislighold. Som kan og bør betraktes som en bug, som vi ikke lenger kan hoppe argumenter, som vi en gang kan ha vært i stand til, uten å gi en verdi, i en syntaks som:

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

fordi det vil kaste! Som gjør det umulig for oss å erstatte vår argument med en bestemt falsy type vår ønsket standardverdi. Som er dumt, siden argumentene objektet er en matrise-lignende objekt og forventes å støtte denne syntaks og konvensjonen som er, opprinnelig eller som standard!

På grunn av denne kortsynte beslutningen kan vi ikke lenger håp om å skrive en funksjon som dette:

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

i så fall, vil vi være i stand til å skrive hver standardverdien av en ønsket type i argumentene rad og kunne i det minste få tilgang til dem ved å args.index.

For eksempel denne funksjonskall ville føre til:

argCheck();
>>undefined 0 false null

som definert i vår standard rekke argumenter verdier. Men følgende er fortsatt mulig:

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

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

Men beklageligvis ikke:

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

Som ellers ville være logging:

>>a 0 false 22

men det er i en bedre verden! Men - for det opprinnelige spørsmålet - den øverste funksjonen vil gjøre det bra. f.eks:

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

PS: beklager for ikke å bevare typer av utvalgte mislighold i mitt argument innganger mens du skriver dem.

Svarte 29/10/2016 kl. 03:44
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more