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.
Top comments (7)
Eu vi esta sintax mas não consigo entender ela. AI vim pesquisar
Mas não acho resposta!
Vc conhece?
const erros = erro => ({
'erro 1':'erro numero 1',
'erro 2':'erro numero 2',
'erro 3':'erro numero 3',
})[erro]|| 'não tem'
console.log(erros('erro1'))
console.log(erros('erro 1'))
Essa sintaxe se chama arrow-function. Basicamente, o código que vc mostrou é equivalente a esse:
Oi, minha questão não é essa.
É o uso desta parte > [erro]|| 'não tem'.
[ ] || 'string'
Não a parte da arrow
Amigo, boa noite.
Essa sintaxe é bem simples, veja, quando você usa arrow function você pode fazer uma one line function, sem return, sem chaves, etc.. Acredito que isto você ja saiba.
Se eu faço uma funcao
Se você passar o valor 1, será printado "O valor foi 1", veja que ele acessa a propriedade do objeto usando o colchete.
Na arrow function ele declara o objeto e ja acessa a propriedade,
Aqui ele tem um objeto com essas 3 propriedades e ele tenta ja acessar uma propriedade dela pelo valor da key que foi passado por parametro.
O "[erro] || não tem " é basicamente que se você passar um valor por parametro que não existe no seu objeto, o valor dará undefined e ele irá para o fallback que é o que depois do ||;
Aquela sintaxe faz mais ou menos isso :
Declarando um objeto e ja acessando uma propriedade dele logo em seguida.
Se a propriedade existir, ela vai printar o Valor foi 1 ou 2, se não existir dará undefined, então eu posso fazer um fallback.
Neste exemplo que eu lhe dei não é uma função, é literalmente um objeto, então não tem parametro, mas voce pode testar criando uma variavel valor com um numero 1 ou 2 , e depois com o numero 3, que nao existe no nosso objeto.
Espero ter ajudado.
Abraços;
Ajudou demais!
Interessante, mas tenho uma pergunta quanto ao uso de objectLiterals:
Tenho um problema, uma tela que pode renderizar 2 layouts diferentes, portanto, as props são dinâmica, pelo menos os valores são.. pois os nomes continuam o mesmo.
Pra isso, imagine que essas props possam vir de 2 custom hooks diferentes.
Na prática, o uso do hook correto dependeria de um ENUM que com seu valor, busca as props certas, do hook correto.
Como não é possível chamar um hook de forma condicional, aparentemente Objects Literals é atraente, já que ele é uma operação chave e valor. Com isso, seria boas práticas criar um object literas que retorna o custom hook correto?
Ex.:
const useFruitsByType = ( fruitsByType ) => {
const fruitsHookMap = {
banana: useBananaProps(),
apple: useAppleProps(),
grapes: useGrapesProps(),
}
return fruitsHookMap[fruitsByType]
}
const {
fruitDescription,
fruitOriginName,
...other props
} = useFruitsByType(banana)
Se essa lista de roles for grande e compartilhada na aplicação, acho que vale a pena.
Se a função é ser um simples switch no campo não vejo motivo para instanciar um objeto de roles na memória para pegar um único ou um conjunto de dados. Principalmente quando essa função é chamada muitas vezes, o malloc e o free ficam doidos. kkk