A instrução switch é uma estrutura condicional que permite executar diferentes blocos de código com base no valor de uma expressão. Ela é especialmente útil quando há múltiplas condições que dependem do mesmo valor, tornando o código mais legível e organizado do que uma longa cadeia de if/else if.

Nesta aula, exploraremos a sintaxe completa do switch, o comportamento peculiar de fall-through (passagem automática entre casos), o papel das palavras-chave break e default, e as situações em que é mais vantajoso usar switch em vez de if/else.

Sintaxe

A sintaxe do switch é composta pela palavra-chave switch seguida de uma expressão entre parênteses e um bloco de código delimitado por chaves. Dentro do bloco, definimos case para cada valor possível, seguido de dois pontos e o código a executar. Opcionalmente, podemos incluir um default para capturar valores não correspondidos.

switch (expressão) {
  case valor1:
    // código para valor1
    break;
  case valor2:
    // código para valor2
    break;
  default:
    // código se nenhum case corresponder
}

A expressão é avaliada uma vez e comparada com cada case usando o operador de igualdade estrita (===). Se houver correspondência, o bloco daquele case é executado até encontrar um break ou o final do switch.

Fall-through

O fall-through ocorre quando um case não termina com break, fazendo com que a execução continue para o próximo case (ou default) independentemente de seu valor corresponder ou não. Esse comportamento pode ser útil em algumas situações, mas geralmente é indesejado e pode levar a bugs.

let fruta = 'maçã';
switch (fruta) {
  case 'banana':
    console.log('Amarela');
  case 'maçã':
    console.log('Vermelha ou verde');
  case 'laranja':
    console.log('Laranja');
    break;
  default:
    console.log('Desconhecida');
}
// Saída:
// Vermelha ou verde
// Laranja

No exemplo, o case 'maçã' não tem break, então após imprimir "Vermelha ou verde", a execução continua para o próximo case ('laranja'), imprimindo "Laranja" e então encontra o break, parando. O fall-through pode ser usado intencionalmente para agrupar vários casos que compartilham o mesmo código.

let dia = 2;
switch (dia) {
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    console.log('Dia útil');
    break;
  case 6:
  case 7:
    console.log('Fim de semana');
    break;
  default:
    console.log('Dia inválido');
}

break e default

A palavra-chave break interrompe a execução do switch e sai do bloco. Sem ela, o fall-through acontece. É uma boa prática sempre incluir break ao final de cada case, a menos que o fall-through seja intencional.

O default é opcional e define um bloco a ser executado se nenhum case corresponder ao valor da expressão. Ele não precisa estar no final do switch, mas por convenção é colocado ao final. Se default não for usado e nenhum case corresponder, nenhum código é executado.

let nota = 7;
switch (true) {
  case nota >= 9:
    console.log('Excelente');
    break;
  case nota >= 7:
    console.log('Bom');
    break;
  case nota >= 5:
    console.log('Regular');
    break;
  default:
    console.log('Insuficiente');
}
// Saída: Bom

Nesse exemplo, usamos switch(true) para simular intervalos, uma técnica avançada que permite usar expressões booleanas nos case.

Quando preferir a if/else

A escolha entre switch e if/else depende da legibilidade e da natureza das condições. Prefira switch quando:

  • Você está comparando uma única variável ou expressão contra múltiplos valores constantes.
  • Os casos são excludentes e o número de opções é grande (mais de 3 ou 4).
  • O código fica mais limpo e organizado.

Prefira if/else quando:

  • As condições envolvem intervalos, expressões complexas ou comparações com diferentes variáveis.
  • Você precisa de lógica mais flexível (operadores lógicos, curto-circuito, etc.).
  • O número de casos é pequeno (2 ou 3).

Em geral, switch é mais adequado para seleção entre valores discretos e fixos, enquanto if/else lida melhor com condições dinâmicas ou não relacionadas a um único valor.

Boas práticas

  • Sempre inclua break ao final de cada case a menos que o fall-through seja intencional e documentado.
  • Use default para tratar valores inesperados, mesmo que seja apenas para logging.
  • Evite switch com muitos casos (mais de 10); considere usar um objeto de mapeamento (dicionário) como alternativa.
  • Mantenha os case com poucas linhas; se o bloco for grande, extraia para uma função.

Referências

Exercícios

  1. Crie um switch que receba um número de 1 a 7 e imprima o dia da semana correspondente (1 = domingo, 2 = segunda, etc.). Use default para números inválidos.

    ✓ Resposta:
    let dia = 3;
    switch (dia) {
      case 1:
        console.log('Domingo');
        break;
      case 2:
        console.log('Segunda');
        break;
      case 3:
        console.log('Terça');
        break;
      case 4:
        console.log('Quarta');
        break;
      case 5:
        console.log('Quinta');
        break;
      case 6:
        console.log('Sexta');
        break;
      case 7:
        console.log('Sábado');
        break;
      default:
        console.log('Dia inválido');
    }
  2. Escreva um switch que, dada uma letra ('a', 'e', 'i', 'o', 'u'), imprima "vogal". Para qualquer outra letra, imprima "consoante ou outro caractere". Use fall-through intencional.

    ✓ Resposta:
    let letra = 'i';
    switch (letra) {
      case 'a':
      case 'e':
      case 'i':
      case 'o':
      case 'u':
        console.log('vogal');
        break;
      default:
        console.log('consoante ou outro caractere');
    }
  3. Explique o que acontece se você omitir o break em um case e dê um exemplo.

    ✓ Resposta:

    Se omitir o break, a execução continua para o próximo case (ou default), causando o fall-through. Exemplo:

    let x = 1;
    switch (x) {
      case 1:
        console.log('Um');
      case 2:
        console.log('Dois');
        break;
      default:
        console.log('Outro');
    }
    // Saída:
    // Um
    // Dois
  4. Reescreva o seguinte código usando switch:

    let cor = 'azul';
    if (cor === 'vermelho') {
      console.log('Pare');
    } else if (cor === 'amarelo') {
      console.log('Atenção');
    } else if (cor === 'verde') {
      console.log('Siga');
    } else {
      console.log('Cor inválida');
    }

    ✓ Resposta:
    let cor = 'azul';
    switch (cor) {
      case 'vermelho':
        console.log('Pare');
        break;
      case 'amarelo':
        console.log('Atenção');
        break;
      case 'verde':
        console.log('Siga');
        break;
      default:
        console.log('Cor inválida');
    }
  5. Crie um switch que receba uma string com o nome de uma estação ('primavera', 'verão', 'outono', 'inverno') e imprima os meses correspondentes (aproximadamente). Use fall-through para agrupar estações que compartilham meses? (opcional).

    ✓ Resposta:
    let estacao = 'verão';
    switch (estacao) {
      case 'primavera':
        console.log('Setembro, Outubro, Novembro');
        break;
      case 'verão':
        console.log('Dezembro, Janeiro, Fevereiro');
        break;
      case 'outono':
        console.log('Março, Abril, Maio');
        break;
      case 'inverno':
        console.log('Junho, Julho, Agosto');
        break;
      default:
        console.log('Estação inválida');
    }