Então, primeiro, o que é uma instrução Switch?
Um switch é uma função que recebe dados, e esses dados serão analisados; se esses dados forem iguais a um de nossos "cases", ele executa a instrução que está inserida no bloco de código e retorna um valor.
function UserPolicy(type) {
switch(type) {
case 'admin':
return `This User is Admin!`
break
case 'client':
return 'This User is Client!'
break
case 'salesman':
return 'This User is Salesman!'
break
default:
return 'Ops, this guy doesn\'t have user profile'
}
}
UserPolicy() // "Ops, this guy doesn't have user profile"
UserPolicy('admin') // "This User is Admin!"
O switch é semelhante às instruções ife else, será avaliado um único valor - dentro da opção, usamos um case para avaliar em relação a cada valor.
Quando você usa muitas declarações de if e else, tem algo muito errado acontecendo, geralmente você deve avaliar usar outra abordagem, aqui está um caso de abuso de if e else:
function UserPolicy(type) {
let userType
if (type === 'admin') {
userType = 'This User is Admin!'
} else if (type === 'client') {
userType = 'This User is Client!'
} else if (type === 'salesman') {
userType = 'This User is Salesman!'
} else {
userType = 'Ops, this guy doesn\'t have user profile'
}
return `User is type: ${userType}`
}
Problemas com o switch
Existem vários problemas com o switch, desde seu fluxo de controle processual até a aparência não padronizada de como ele lida com blocos de código, o restante do JavaScript usa chaves, mas o switch não. Sintaticamente, não é um dos melhores do JavaScript, nem o seu design. Somos forçados a adicionar breaks manualmente; instruções em cada case, o que pode levar a erros difíceis de depuração e aninhados futuramente, caso nos esqueçamos! Temos que tratar isso com muita cautela.
Costumamos usar pesquisas de objeto para muitas coisas em JavaScript, muitas vezes para coisas que nunca contemplaríamos usando o switch - então por que não usar um Object Literal para substituir o switch? Os objetos são muito mais flexíveis, têm melhor legibilidade e capacidade de manutenção e não precisamos quebrar manualmente; cada case. Eles também são muito mais amigáveis com os novos desenvolvedores de JavaScript, pois são objetos por padrão.
Motivos para não usar switch
À medida que o número de cases aumenta, o desempenho do objeto (tabela de hash) fica melhor que o custo médio do switch(a ordem da questão do caso). A abordagem de objeto é uma pesquisa de tabela de hash, e a opção deve avaliar cada case até que ele atinja uma correspondência e uma quebra.
Object Literals são mais sustentáveis e legíveis. Também não precisamos nos preocupar com "breaks"; declarações e casos que se enquadram - é apenas um objeto simples.
Normalmente, colocaríamos um switch dentro de uma função e obteríamos um valor de retorno. Vamos fazer o mesmo aqui e transformar o switch case em uma função utilizável com retorno de um Object Literal:
function UserPolicy(type) {
// Criamos uma constante que recebe um objeto, e cada uma das propriedades
// será os valores correspondentes aos nossos types
const Users = {
admin: 'This User is Admin!',
client: 'This User is Client!',
salesman: 'This User is Salesman!',
default: 'Ops, this guy doesn\'t have user profile'
}
return Users[type] || Users.default
}
UserPolicy() // "Ops, this guy doesn't have user profile"
UserPolicy('admin') // "This User is Admin!"
Visão global
Object Literals é um controle mais natural do fluxo em JavaScript, o switch é um pouco antigo, desajeitado e propenso a erros de difícil depuração. Os objetos são mais extensíveis, sustentáveis e podemos testá-los muito melhor. Eles também fazem parte de um padrão de design e são comumente usados diariamente em outras tarefas de programação. Os Object Literals podem conter funções e qualquer outro tipo de objeto, o que os torna realmente flexíveis! Cada função no literal também tem escopo de função, para que possamos retornar o fechamento da função pai.
// Não estou ditando regra - é apenas mais uma forma de solucionar os problemas do nosso dia a dia.