
Existem quatro maneiras de escrever switch JavaScript, você conhece? Se você sabe ou não, eu não sei.
Só existe uma maneira de escrever a instrução switch JavaScript que eu conheço. Mas quando se trata de lidar com ramificações, há muitas maneiras de escrevê-las. O método de escrita de ramificação if pode ser contado como um, o método de escrita de ramificação switch pode ser contado como o segundo e o terceiro é usar o modo de estratégia. Se os operadores condicionais também estiverem incluídos, bem, existem exatamente quatro.
mas o protagonista deste artigo é switch. Todo mundo sabe que switch geralmente é escrito como uma variável ou expressão switch e uma constante case. Bem, por exemplo, para uma pontuação de cem pontos, 90 e acima é considerado excelente, 80 e acima e abaixo de 90 são considerados bons, 60 e acima e abaixo de 80 são considerados qualificados e abaixo de 60 são considerados não qualificados. provavelmente seria escrito assim:
function calcGrade(score ) {
linha const = pontuação/10 |
mudar (linha) {
caso 10: caso 9:
retornar "Excelente";
caso 8:
retornar "bom";
caso 7: caso 6:
retornar “qualificado”;
padrão:
retornar "não qualificado";
}
} No código, score / 10 | 0 tem o mesmo efeito que Math.floor(score / 10) , que é dividir por 10 para obter a parte inteira do quociente.
Essa opção é usada muito bem, e o método de arredondamento para evitar o uso de uma longa lista de ramificações if...else também é um truque inteligente.
Mas agora as regras mudaram e o ponto de separação entre qualificados e bons foi reduzido de 80 para 75 pontos. O que devemos fazer?
O método de arredondamento acima ainda é possível, mas desta vez o divisor não é mais 10, mas 5. Da mesma forma, existem muitos mais casos:
É melhor usar 9 casos. se... mais.
É? Na verdade, existe uma maneira mais simples de escrever usando switch:
function calcGrade(score) {
mudar (verdadeiro) {
pontuação do caso >= 90:
retornar "Excelente";
pontuação do caso >= 75:
retornar "bom";
pontuação do caso >= 60:
retornar “qualificado”;
padrão:
retornar "não qualificado";
}
} Parece um pouco estranho? Esta não é a constante de case da expressão switch usual, mas exatamente o oposto, a expressão case da constante switch! Se você pegar este programa e executá-lo, descobrirá que não há problema algum. Porque - switch e case são combinados de acordo com === , não importa se é uma expressão ou uma constante, ou em outras palavras, switch e case podem ser seguidos por uma expressão!
Sim, expressão!
Portanto, no exemplo acima, alterar switch(true) switch( 2 > 1) tem o mesmo efeito.
Ok, minha mente está aberta. Não importa quantas maneiras você pode escrever switch. A próxima coisa a observar é a variante switch.
: vi que C# tem uma expressão switch e estou com ciúmes.
Não se preocupe, tudo em JavaScript pode ser uma expressão... Caso contrário, basta usar IIFE para encapsular uma
função calcGrade(score) {
retornar (valor => {
mudar (verdadeiro) {
valor do caso >= 90:
retornar "Excelente";
valor do caso >= 75:
retornar "bom";
valor do caso >= 60:
retornar “qualificado”;
padrão:
retornar "não qualificado";
}
})(pontuação);
} Observe que score é usado como parâmetro do IIFE aqui porque, no uso real, pode ser necessário transmitir uma expressão. Neste caso deve ser avaliado antecipadamente e apenas uma vez (para evitar efeitos secundários de substituição).
No entanto, esse encapsulamento obviamente não tem sentido. Se você realmente deseja encapsulá-lo assim, é melhor encapsulá-lo como uma estratégia:
function calcGrade(score) {.
return ((valor, regras) => regras.find(({ t }) => t(valor)).v)(
pontuação,
[
{ t: n => n >= 90, v: "Excelente" },
{ t: n => n >= 75, v: "Bom" },
{ t: n => n >= 60, v: "Qualificado" },
{ t: () => verdadeiro, v: "não qualificado" },
]
);
} Cada estratégia é um objeto contendo um testador ( t ) e um valor ( v ). testador é uma função de julgamento que passa o valor que precisa ser julgado, que é a expressão aqui em switch (表达式) , e essa expressão também é passada como parâmetro do IIFE após ser avaliada antecipadamente. O processo de aplicação de uma estratégia é simples e rudimentar, que consiste em encontrar a primeira estratégia que satisfaça as condições e retirar o seu valor.
Claro, esta estratégia é um pouco exagerada. Quando você realmente precisa usar uma estratégia, a estratégia geralmente não é um valor, mas sim um comportamento, ou seja, uma função.
Sabemos que na instrução switch cada case está no mesmo escopo, portanto a mesma variável local não pode ser declarada em duas instruções case. Embora agrupar com { } possa resolver esses problemas, o código não parece muito bom, especialmente tome cuidado para não esquecer break . Se você usar uma estratégia, ela pode parecer agradável à vista e você não precisa se preocupar com o problema do intervalo:
aqui, para fins de demonstração, no comportamento da estratégia, os resultados serão exibidos primeiro e depois o nível será voltou.
function calcGrade(pontuação) {
return ((valor, regras) => regras.find(({ t }) => t(valor)).fn(valor))(
pontuação,
[
{
t: n => n >= 90,
fn: pontuação => {
const nota = "Excelente";
console.log(nota, pontuação);
nota de retorno;
}
},
{
t: n => n >= 75,
fn: pontuação => {
nota const = "bom";
console.log(nota, pontuação);
nota de retorno;
}
},
{
t: n => n >= 60,
fn: pontuação => {
const nota = "aprovado";
console.log(nota, pontuação);
nota de retorno;
}
},
{
t: () => verdadeiro,
fn: pontuação => {
nota const = "não qualificado";
console.log(nota, pontuação);
nota de retorno;
}
},
]
);
} O código é realmente um pouco longo porque contém uma lógica de comportamento estratégico. Se realmente vai ser usado como uma expressão switch, a parte da estratégia deve ser uma expressão, não muito longa. No código acima, o comportamento da estratégia é semelhante e pode ser encapsulado em uma função, para que possa ser escrito na forma de uma expressão:
function calcGrade(score) {
const printGrade = (nota, pontuação) => {
console.log(nota, pontuação);
nota de retorno;
};
return ((valor, regras) => regras.find(({ t }) => t(valor)).fn(valor))(
pontuação,
[
{ t: n => n >= 90, fn: pontuação => printGrade("Excelente", pontuação) },
{ t: n => n >= 75, fn: pontuação => printGrade("Bom", pontuação) },
{ t: n => n >= 60, fn: pontuação => printGrade("qualificado", pontuação) },
{ t: () => true, fn: pontuação => printGrade("não qualificado", pontuação) },
]
);
} Parece apresentável agora?
Os códigos acima têm formas diferentes e fazem coisas semelhantes, e não há comparação de qual é o melhor. Não importa o que você goste, você é elegante; não importa o que você não goste, você não é favorecido. Em diferentes situações, basta escolher a abordagem adequada. O código acima usa find() para encontrar a estratégia. Se filter() for usado, a história será diferente.