2012-01-05 5 views
28

Ho recentemente appreso che è possibile utilizzare un'istruzione switch ordinata, con falltrough per impostare valori degli argomenti di default in Javascript:E 'una buona idea usare uno switch con fallthrough per gestire gli argomenti predefiniti in Javascript?

function myFunc(arg1, arg2, arg3) { 
    //replace unpassed arguments with their defaults: 
    switch (arguments.length) { 
     case 0 : arg1 = "default1"; 
     case 1 : arg2 = "default2"; 
     case 2 : arg3 = "default3"; 
    } 
} 

ho imparato ad apprezzare molto, dal momento che non solo è molto breve, ma anche opere sulla base di parametri effettivamente passati, senza affidarsi a avere una classe speciale di valori (null, falsy, ecc) servire come segnaposto come nelle versioni più tradizionali:

function myFunc(arg1, arg2, arg3){ 
    //replace falsy arguments with their defaults: 
    arg1 = arg1 || "default1"; 
    arg2 = arg2 || "default2"; 
    arg3 = arg3 || "default3"; 
} 

mio inital anche se dopo aver visto la versione con il l'interruttore era che dovrei considerare di usarlo "di default" sopra la versione ||.

L'interruttore fallthough rende non molto più lungo e ha il vantaggio che è molto più "robusto", in quanto non si preoccupa i tipi di parametri. Nel caso generale, sembra una buona idea non doversi preoccupare di cosa accadrebbe con tutti i valori di falsy ('', 0, null, false ...) ogni volta che devo fare una funzione con i parametri di default.

Vorrei quindi riservare il arg = arg || x per i casi reali in cui voglio verificare la verità invece di riproporlo come regola generale per l'impostazione dei parametri.

Tuttavia, ho trovato very few esempi di questo modello quando ho fatto un code search per questo, così ho dovuto mettere sul mio cappello scettico. Perché non ho trovato altri esempi di questo idioma?

  • È solo ora molto noto?
  • Non ho cercato abbastanza bene? Sono stato confuso dal gran numero di falsi positivi?
  • C'è qualcosa che lo rende inferiore alle alternative?

Alcuni motivi che io (e alcuni dei commenti) potuto pensare per evitare switch(arguments.length):

  • Uso parametri denominati passati attraverso un oggetto letterale è molto flessibile ed estensibile. Forse i posti dove più argomenti possono essere opzionali stanno usando questo?

  • Forse la maggior parte delle volte do desidera verificare la verità? Utilizzando una categoria di valori come palceholders permette anche parametri di default a comparire in mezzo invece che solo alla fine: myFunc('arg1', null, 'arg3')

  • Forse la maggior parte delle persone preferiscono la brevissima arg = arg || "default" e la maggior parte del tempo noi non si preoccupano valori falsi?

  • Forse l'accesso a arguements è malvagio/non performante?

  • Forse questo tipo di caso di commutazione è una brutta parte a cui non ho pensato?

sono questi svantaggi sufficienti a evitare l'uso di switch(arguments.length) come un modello argomento fiocco di default o è un trucco che dovrei mantenere e utilizzare nel mio codice?

+7

non ho mai saputo di questo idioma, ma guardando essa v'è almeno un avvertimento che posso vedere - passando 'undefined' rende 'arguments.length === 2', mentre probabilmente si vuole sostituire un' passato undefined' con il valore predefinito pure (come '||' fa). – pimvdb

+2

Approccio interessante. Anche se funzionerebbe solo se uno fornisce sempre tutti i parametri precedenti. Ad esempio, jQuery consente di omettere i parametri nel mezzo, come '$ .get (url, callback)' invece di '$ .get (url, data, callbacl)'. 'switch' non può fare la distinzione tra diversi tipi di parametri. Avrebbe anche esito negativo se vengono passati "parametri di riempimento", come 'foo (1, null, 3)' perché si vuole impostare il terzo parametro ma non il secondo (* edit * cosa dice pimvdb). Quindi forse questi sono i motivi per cui non è così popolare; non è abbastanza flessibile –

+2

Penso che un altro motivo per cui non viene utilizzato, è perché richiede un lavoro aggiuntivo se si refactoring il metodo per avere una firma diversa mentre il metodo tipico funzionerebbe ancora bene. –

risposta

6

Poiché la domanda è stata aggiornata, è davvero una questione di opinione. Ci sono un certo numero di funzioni javascript che molte persone suggeriscono di evitare, come switch e ternario. Questo è il motivo per cui non ci sono molte informazioni su alcune di queste funzionalità.

Il motivo per cui viene suggerito è perché molte persone non utilizzano queste funzionalità e creano problemi nel codice. I bug sono a volte difficili da rilevare e può essere difficile per gli altri capire cosa sta facendo il tuo codice (in particolare chi non ha familiarità con javascript o nuovi programmatori).

Quindi, se ti piace farlo in questo modo, non sei preoccupato delle opinioni (o del livello di abilità) di chiunque lavori sul tuo codice. Con tutti i mezzi, il tuo approccio funzionerà. Ho usato l'istruzione switch di tanto in tanto, e anche se non penso che sia davvero "buono" o "cattivo", è difficile trovare una situazione che sia che richiede.

ti ha chiesto come potrei andare su questo senza un altro, se a catena:

function myFunc(args) { 
    var allArgs = { 
     arg1:"default1", 
     arg2:"default2", 
     arg3:"default3" 
    }; 
    for (var key in args) { 
     allArgs[key] = args[key];   
    } 
} 
myFunc({arg1:null, arg3:'test'}) 
+0

Penso che lo schema di commutazione fosse più orientato per quando la funzione riceve argomenti da una lista come in 'f (arg1, arg2)'. Ma avete un punto nel dire che l'intera discussione è irrilevante in quanto i parametri denominati di solito sono solo migliori. – hugomg

6

Solo un'ipotesi, ma Doug Crockford scoraggia l'uso delle istruzioni switch in "JavaScript: le parti buone". La sua logica è che le istruzioni switch sono una fonte comune di bug perché è difficile individuarli quando si utilizza la logica 'fall through'. È facile vedere quando viene attivato un caso, ma spesso è difficile determinare se tutti i casi in un set di risultati sono stati coperti, specialmente se non è il tuo codice.

+0

+1 Probabilmente c'è un modo migliore per realizzare ciò che stai cercando di fare senza usare un'istruzione switch. alcune informazioni sulle parti buone o cattive di javascript: http://www.youtube.com/watch?v=RO1Wnu-xKoY –

+0

@NickHagianis: quale sarebbe l'alternativa qui però?Il solito stile '||' ha una semantica diversa (come discusso nella domanda) e l'uso di una catena 'if-else' è * molto * più prolisso. – hugomg

+0

Questa è una buona risposta alla domanda: "Perché non ho trovato altri esempi di questo idioma?" Ma non sono sicuro che la logica regga. Molti programmatori JavaScript sembrano pensare che le opinioni di Crockford su quali parti di JavaScript siano "buone" e "cattive" sono universalmente veritiere. Personalmente, non sono d'accordo con Crockford qui: le dichiarazioni sugli switch possono essere bizzarre, ma non le ho mai trovate una fonte significativa di bug in alcun codice che li usi. –