Hay cuatro formas de escribir un interruptor de JavaScript, ¿lo conoces? Lo sepas o no, no lo sé.
Que yo sepa, solo hay una forma de escribir la declaración de cambio de JavaScript. Pero cuando se trata de manejar ramas, hay muchas maneras de escribirlas. El método de escritura de rama if se puede contar como uno, el método de escritura de rama de cambio se puede contar como el segundo y el tercero es usar el modo de estrategia. Si también se incluyen operadores condicionales, bueno, hay exactamente cuatro.
pero el protagonista de este artículo es switch. Todo el mundo sabe que switch generalmente se escribe como una variable o expresión de cambio y una constante de caso. Bueno, por ejemplo, para una puntuación de cien puntos, 90 o más se considera excelente, 80 o más y menos de 90 se consideran buenos, 60 o más y menos de 80 se consideran calificados y menos de 60 se considera no calificado. probablemente se escribiría así:
function calcGrade(score) { línea constante = puntuación / 10 | cambiar (línea) { caso 10: caso 9: devolver "Excelente"; caso 8: devolver "bueno"; caso 7: caso 6: devolver "calificado"; por defecto: devolver "no calificado"; } }
En el código, score / 10 | 0
tiene el mismo efecto que Math.floor(score / 10)
, que consiste en dividir por 10 para obtener la parte entera del cociente.
Este modificador se usa bastante bien, y el método de redondeo para evitar el uso de una larga lista de ramas if...else también es un truco inteligente.
Pero ahora las reglas han cambiado y el punto de separación entre calificados y buenos se ha reducido de 80 puntos a 75 puntos. ¿Qué debemos hacer?
El método de redondeo anterior todavía es posible, pero esta vez el divisor ya no es 10, sino 5. En consecuencia, hay muchos más casos:
Es mejor usar 9 casos. si... más.
¿Es? De hecho, existe una forma más sencilla de escribir usando switch:
function calcGrade(score) { cambiar (verdadero) { puntuación del caso >= 90: devolver "Excelente"; puntuación del caso >= 75: devolver "bueno"; puntuación del caso >= 60: devolver "calificado"; por defecto: devolver "no calificado"; } }
¿Se siente un poco extraño? Esta no es la constante de caso de expresión de cambio habitual, sino exactamente lo contrario, ¡expresión de caso de constante de cambio! Si toma este programa y lo ejecuta, encontrará que no hay ningún problema. Debido a que - switch y case coinciden según ===
, no importa si es una expresión o una constante, o en otras palabras, switch y case pueden ir seguidos de una expresión.
¡Sí, expresión!
Entonces, en el ejemplo anterior, cambiar switch(true)
switch( 2 > 1)
tiene el mismo efecto.
Está bien, mi mente está abierta. No importa de cuántas maneras puedas escribir switch. Lo siguiente a tener en cuenta es la variante Switch.
: vi que C# tiene una expresión de cambio y estoy celoso. ¿Se puede implementar?
No te preocupes, todo en JavaScript puede ser una expresión... Si no, simplemente usa IIFE para encapsular una
función calcGrade(score) { retorno (valor => { cambiar (verdadero) { valor de caso >= 90: devolver "Excelente"; valor de caso >= 75: devolver "bueno"; valor de caso >= 60: devolver "calificado"; por defecto: devolver "no calificado"; } })(puntaje); }
Tenga en cuenta que score
se utiliza aquí como parámetro de IIFE porque, en el uso real, es posible que sea necesario pasar una expresión. En este caso se debe evaluar previamente y sólo una vez (para evitar efectos secundarios de sustitución).
Sin embargo, dicha encapsulación obviamente no tiene sentido. Si realmente desea encapsularla de esta manera, es mejor encapsularla como una estrategia:
function calcGrade(score) { return ((valor, reglas) => reglas.find(({ t }) => t(valor)).v)( puntaje, [ { t: n => n >= 90, v: "Excelente" }, { t: n => n >= 75, v: "Bueno" }, { t: n => n >= 60, v: "Calificado" }, { t: () => verdadero, v: "no calificado" }, ] ); }
Cada estrategia es un objeto que contiene un probador ( t
) y un valor ( v
). tester es una función de juicio que pasa el valor que necesita ser juzgado, que es la expresión aquí en switch (表达式)
, y esta expresión también se pasa como parámetro de IIFE después de ser evaluada por adelantado. El proceso de aplicación de una estrategia es simple y burdo, que consiste en encontrar la primera estrategia que cumpla las condiciones y sacar su valor.
Por supuesto, esta estrategia es un poco exagerada. Cuando realmente necesitas usar una estrategia, la estrategia generalmente no es un valor, sino un comportamiento, es decir, una función.
Sabemos que en la declaración de cambio, cada caso está en el mismo alcance, por lo que la misma variable local no se puede declarar en dos declaraciones de caso. Aunque envolver con { }
puede resolver estos problemas, el código no se ve muy bien, especialmente tenga cuidado de no olvidar break
. Si usa una estrategia, puede parecer agradable a la vista y no tiene que preocuparse por el problema de la ruptura:
aquí, con fines de demostración, en el comportamiento de la estrategia, los resultados se generarán primero y luego el nivel será regresó.
función calcCalificación(puntuación) { return ((valor, reglas) => reglas.find(({ t }) => t(valor)).fn(valor))( puntaje, [ { t: n => n >= 90, fn: puntuación => { calificación constante = "Excelente"; console.log(calificación, puntuación); calificación de devolución; } }, { t: n => n >= 75, fn: puntuación => { calificación constante = "buena"; console.log(calificación, puntuación); calificación de retorno; } }, { t: n => n >= 60, fn: puntuación => { calificación constante = "aprobado"; console.log(calificación, puntuación); calificación de retorno; } }, { t: () => verdadero, fn: puntuación => { calificación constante = "no calificado"; console.log(calificación, puntuación); calificación de retorno; } }, ] ); }
De hecho, el código es un poco largo porque contiene una lógica de comportamiento estratégico. Si realmente se va a utilizar como expresión de cambio, la parte de estrategia debe ser una expresión, no demasiado larga. En el código anterior, el comportamiento de la estrategia es similar y se puede encapsular en una función, de modo que se pueda escribir en forma de expresión:
function calcGrade(score) { const printGrade = (calificación, puntuación) => { console.log(calificación, puntuación); calificación de retorno; }; return ((valor, reglas) => reglas.find(({ t }) => t(valor)).fn(valor))( puntaje, [ { t: n => n >= 90, fn: puntuación => printGrade("Excelente", puntuación) }, { t: n => n >= 75, fn: puntuación => printGrade("Bueno", puntuación) }, { t: n => n >= 60, fn: puntuación => printGrade("calificado", puntuación) }, { t: () => verdadero, fn: puntuación => printGrade("no calificado", puntuación) }, ] ); }
¿Se ve presentable ahora?
Los códigos anteriores tienen diferentes formas y hacen cosas similares, y no hay comparación de cuál es mejor. No importa lo que te guste, eres elegante; no importa lo que no te guste, no eres favorecido. En diferentes situaciones, simplemente elija el enfoque adecuado. El código anterior usa find()
para encontrar la estrategia. Si en su lugar se usa filter()
, será una historia diferente.