2012-01-05 13 views
28

he sabido recientemente que se puede utilizar una sentencia switch ordenada con fallthrough para establecer valores de los argumentos por defecto en Javascript:¿Es una buena idea usar un conmutador con Fallthrough para manejar los argumentos predeterminados en 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"; 
    } 
} 

que han crecido a gustar mucho, ya que no sólo es muy corto, pero también obras basadas en parámetros pasados ​​realmente, sin depender de tener una clase especial de valores (null, Falsy, etc.) sirven como marcadores de posición al igual que en las versiones más tradicionales:

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

Mi inital aunque después de ver la versión que utiliza el cambio fue que debería considerar usarlo "por defecto" sobre la versión ||.

El interruptor se carece aunque hace que no sea mucho más largo y tiene la ventaja de que es mucho más "robusto" en cuanto a que no se preocupa por los tipos de los parámetros. En el caso general, parece una buena idea no tener que preocuparse por lo que sucedería con todos los valores falsy ('', 0, null, false ...) cada vez que tuviera que hacer una función con parámetros predeterminados.

Yo reservaría el arg = arg || x para los casos reales en los que deseo verificar la verosimilitud en lugar de reutilizarlo como la regla general para el incumplimiento de parámetros.

Sin embargo, encontré very few ejemplos de este patrón cuando hice un code search para él así que tuve que ponerme mi sombrero escéptico. ¿Por qué no encontré más ejemplos de este modismo?

  • ¿Es ahora muy conocido?
  • ¿No busqué lo suficiente? ¿Me confundí con la gran cantidad de falsos positivos?
  • ¿Hay algo que lo haga inferior a las alternativas?

Algunas de las razones que yo (y algunos de los comentarios) podía imaginar para evitar switch(arguments.length):

  • Uso de parámetros con nombre pasados ​​a través de un objeto literal que es muy flexible y extensible. Tal vez los lugares donde más argumentos pueden ser opcionales están usando esto en su lugar?

  • Tal vez la mayoría de las veces ¿ quiere comprobar la veracidad? Usando una categoría de valores como palceholders también permite a los parámetros por defecto aparecen en el medio en lugar de sólo al final: myFunc('arg1', null, 'arg3')

  • Tal vez la mayoría de la gente simplemente prefieren el muy corto arg = arg || "default" y la mayoría de las veces simplemente no importa valores falsy?

  • Quizás accediendo arguements es malo/unperformant?

  • Tal vez este tipo de casos interruptor fallthrough tiene una parte mala Yo no pienso?

Son estos inconvenientes suficientes para evitar el uso de switch(arguments.length) como un patrón argumento por defecto básico o es un truco que debería tener y usar en mi código?

+7

nunca supe de este idioma, pero viendo que hay por lo menos una advertencia que puedo ver - que pasa 'undefined' hace 'arguments.length === 2', mientras que probablemente quiera reemplazar un' undefined' pasado con el valor predeterminado también (como '||' lo hace). – pimvdb

+2

Enfoque interesante. Aunque solo funcionaría si uno proporciona siempre todos los parámetros anteriores. Por ejemplo, jQuery le permite omitir parámetros en el medio, como '$ .get (url, callback)' en lugar de '$ .get (url, data, callbacl)'. 'switch' no pudo hacer la distinción entre diferentes tipos de parámetros. También fallaría si se pasan los "parámetros de relleno", como 'foo (1, null, 3)' porque uno quiere establecer el tercer parámetro pero no el segundo (* editar * lo que dijo pimvdb). Entonces quizás estas sean las razones por las que no es tan popular; no es lo suficientemente flexible –

+2

Creo que otra razón por la que no se usa es porque requiere trabajo adicional si refactoriza el método para tener una firma diferente, mientras que el método típico funcionaría bien. –

Respuesta

6

Dado que la pregunta se ha actualizado, es realmente una cuestión de opinión. Hay una serie de características de javascript que muchas personas sugieren evitar, como el cambio y el ternario. Esta es la razón por la cual no hay mucha información sobre algunas de esas características.

La razón por la que se hace esta sugerencia es porque muchas personas pierden el uso de esas características y crean problemas en su código. Los errores a veces son difíciles de detectar y puede ser difícil para otros comprender qué está haciendo su código (especialmente aquellos que no están familiarizados con javascript o programadores nuevos).

Así que si le gusta hacerlo de esa manera, y no le preocupan las opiniones (o el nivel de habilidad) de cualquiera que trabaje en su código. Por supuesto, su enfoque funcionará. En ocasiones, he usado la declaración de cambio y, aunque no creo que sea realmente "buena" o "mala", es difícil encontrar una situación que requiera.

Se preguntó cómo podría ir sobre esto sin una cadena de else if-:

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

Creo que el patrón de conmutación estaba más orientado para cuando la función recibe argumentos de una lista como en 'f (arg1, arg2)'. Pero usted tiene razón al decir que toda la discusión es irrelevante, ya que los parámetros nombrados son usualmente mejores. – hugomg

6

Solo una conjetura, pero Doug Crockford desalienta el uso de declaraciones de interruptor en 'JavaScript: las partes buenas'. Su lógica es que las declaraciones de cambio son una fuente común de errores porque es difícil ubicarlos cuando se utiliza la lógica de 'atravesar'. Es fácil de ver cuando se desencadena un caso, pero a menudo es difícil determinar si se han cubierto todos los casos en un conjunto de resultados, especialmente si no es su código.

+0

+1 Probablemente haya una mejor manera de lograr lo que estás tratando de hacer sin usar una declaración de cambio. algo de información sobre buenas y malas partes de javascript: http://www.youtube.com/watch?v=RO1Wnu-xKoY –

+0

@NickHagianis: ¿Cuál sería la alternativa aquí?El estilo usual '||' tiene una semántica diferente (como se explica en la pregunta) y el uso de una cadena 'if-else' es * mucho * más detallado. – hugomg

+0

Esta es una buena respuesta a la pregunta: "¿Por qué no encontré más ejemplos de este modismo?" Pero no estoy seguro de que la lógica se mantenga. Muchos programadores de JavaScript parecen pensar que las opiniones de Crockford sobre qué partes de JavaScript son "buenas" y "malas" son universalmente ciertas. Personalmente, no estoy de acuerdo con Crockford aquí: cambiar las declaraciones puede ser peculiar, pero nunca he encontrado que sean una fuente importante de errores en ningún código que los use. –

Cuestiones relacionadas