DEV Community

Tauan Tathiell
Tauan Tathiell

Posted on

Substitua sua instrução switch e vários "if and else", usando Object Literals - [pt-BR].

Alt Text

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!"
Enter fullscreen mode Exit fullscreen mode

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}`
}
Enter fullscreen mode Exit fullscreen mode

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!"
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
urielsouza29 profile image
Uriel dos Santos Souza

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'))

Collapse
 
betopompolo profile image
Adalberto Pompolo

Essa sintaxe se chama arrow-function. Basicamente, o código que vc mostrou é equivalente a esse:

function erros(erro) {
  return {
    'erro 1': 'erro numero 1',
    'erro 2': 'erro numero 2',
    'erro 3': 'erro numero 3',
  }
}

console.log(erros('erro1'))
console.log(erros('erro 1'))
Enter fullscreen mode Exit fullscreen mode
Collapse
 
urielsouza29 profile image
Uriel dos Santos Souza

Oi, minha questão não é essa.
É o uso desta parte > [erro]|| 'não tem'.

[ ] || 'string'

Não a parte da arrow

Thread Thread
 
pedrosarkis profile image
Pedro Penha Verani

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

function(valor) {
const obj =  {
1: 'O valor foi 1',
2: 'O valor foi 2',
}
return obj[valor]
}
Enter fullscreen mode Exit fullscreen mode

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,

const erros = erro => ({'erro 1':'erro numero 1','erro 2':'erro numero 2', 'erro 3':'erro numero 3',})[erro]
Enter fullscreen mode Exit fullscreen mode

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 :

const teste = {
1: 'O valor foi 1',
2: 'O valor foi 2',
}[valor] 
Enter fullscreen mode Exit fullscreen mode

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.

const teste2 = {
1: 'O valor foi 1',
2: 'O valor foi 2',
}[valor] || 'nada'; 
Enter fullscreen mode Exit fullscreen mode

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.

const valor = 1; 

const teste3 = {
1: 'O valor foi 1',
2: 'O valor foi 2',
}[valor] || 'nada';

teste3 == 'O valor foi 1'
Enter fullscreen mode Exit fullscreen mode
const valor = 3;
const teste4 = {
1: 'O valor foi 1',
2: 'O valor foi 2',
}[valor] || 'nada';

teste4 == 'nada'; 
Enter fullscreen mode Exit fullscreen mode

Espero ter ajudado.
Abraços;

Thread Thread
 
urielsouza29 profile image
Uriel dos Santos Souza

Ajudou demais!

Collapse
 
danielcnascimento profile image
danielcnascimento

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)

Collapse
 
sandhilt profile image
Bruno Ochotorena

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