Decisões explícitas no fluxo do programa

Estruturas condicionais implementam ramificações: o programa escolhe qual bloco executar com base em expressões booleanas. Quase toda regra de negócio — permissões, precificação, validação de formulário — passa por condicionais bem desenhadas.

if, else if, else

function calcularTarifa(consumoKwh, temBeneficioSocial) {
  if (consumoKwh < 0) {
    throw new Error('Consumo inválido');
  }

  if (temBeneficioSocial) {
    return consumoKwh * 0.45;
  }

  if (consumoKwh <= 100) {
    return consumoKwh * 0.75;
  }

  if (consumoKwh <= 200) {
    return 100 * 0.75 + (consumoKwh - 100) * 1.10;
  }

  return 100 * 0.75 + 100 * 1.10 + (consumoKwh - 200) * 1.40;
}

Faixas encadeadas exigem atenção aos limites: valor exatamente 100 cai na segunda faixa; valor 200.01 entra na terceira. Documente inclusividade em comentário ou teste unitário.

switch para estados discretos

function proximaAcaoPedido(status) {
  switch (status) {
    case 'CRIADO':
      return 'Aguardar pagamento';
    case 'PAGO':
      return 'Separar estoque';
    case 'ENVIADO':
      return 'Exibir rastreio';
    case 'ENTREGUE':
      return 'Encerrar';
    case 'CANCELADO':
      return 'Arquivar';
    default:
      throw new Error(`Status desconhecido: ${status}`);
  }
}

default que lança erro evita silenciar integrações quebradas — preferível a retornar string genérica “desconhecido”.

Diagrama PlantUML

Operador ternário com moderação

const label = pedido.urgente ? 'Prioritário' : 'Normal';

Útil para atribuições simples. Evite ternários aninhados — legibilidade cai rapidamente em code review.

Truthy e falsy em JavaScript

Valores que convertem para false em contexto booleano: 0, '', null, undefined, NaN. Cuidado: '0' é string truthy. Para presença de array, prefira lista.length > 0 em vez de só if (lista) quando lista vazia é válida.

Guard clauses em APIs reais

function transferir(origem, destino, valor) {
  if (!origem || !destino) throw new Error('Contas obrigatórias');
  if (valor <= 0) throw new Error('Valor positivo exigido');
  if (origem.saldo < valor) throw new Error('Saldo insuficiente');
  if (origem.id === destino.id) throw new Error('Mesma conta');

  origem.saldo -= valor;
  destino.saldo += valor;
  return { ok: true, valor, timestamp: Date.now() };
}

Testes manuais sistemáticos

Para cada condicional, liste:

  • Caminho feliz (happy path)
  • Limites exatos (boundary)
  • Entradas inválidas
  • Combinações de flags (assinante + cupom + produto digital)

Estudo de caso: sistema de aprovação de despesas

Regras combinadas em ambiente corporativo:

  • Até R$ 500: aprovação automática se centro de custo ativo.
  • R$ 500,01 a R$ 5.000: requer gestor direto.
  • Acima de R$ 5.000: comitê financeiro.
  • Despesas em categoria “viagem” exigem anexo, independente do valor.
  • Funcionário em período de experiência: teto R$ 200 automático.
function rotearDespesa(despesa, funcionario) {
  if (!despesa.categoria || despesa.valor == null) {
    return { nivel: 'ERRO', motivo: 'Dados incompletos' };
  }

  if (despesa.categoria === 'viagem' && !despesa.anexo) {
    return { nivel: 'ERRO', motivo: 'Anexo obrigatório para viagem' };
  }

  if (funcionario.emExperiencia && despesa.valor > 200) {
    return { nivel: 'GESTOR', motivo: 'Teto em experiência' };
  }

  if (despesa.valor <= 500 && funcionario.centroCustoAtivo) {
    return { nivel: 'AUTO' };
  }

  if (despesa.valor <= 5000) {
    return { nivel: 'GESTOR' };
  }

  return { nivel: 'COMITE' };
}

Implemente e teste pelo menos oito combinações. Documente expected vs actual numa planilha — prática comum em QA manual de regras de negócio.

Refatoração: extrair condições nomeadas

function podeAprovarAutomaticamente(despesa, funcionario) {
  const valorOk = despesa.valor <= 500;
  const centroAtivo = funcionario.centroCustoAtivo === true;
  const naoExperiencia = !funcionario.emExperiencia;
  return valorOk && centroAtivo && naoExperiencia;
}

Nomes booleanos legíveis reduzem comentários redundantes e facilitam code review.

Para aprofundar na web

Para entender melhor este tema, pesquise por:

  • "if else JavaScript MDN" — sintaxe e boas práticas oficiais
  • "switch case JavaScript quando usar" — estados discretos vs cadeia de if
  • "early return guard clauses" — reduzir aninhamento em funções
  • "operador ternário JavaScript legibilidade" — quando simplifica vs confunde
  • "validação de entrada função programação" — falhar cedo com mensagem clara

Implemente a mesma regra de negócio duas vezes: com if encadeado e com switch — compare legibilidade.

Atividades

  1. Por que default em switch deve lançar erro para status desconhecido?

    • A) Performance
    • B) Detectar integrações desatualizadas cedo
    • C) Obrigação da linguagem
    • D) Substituir logs
    Ver resposta

    Resposta correta: B) Detectar integrações desatualizadas cedo

    Estados não mapeados indicam bug ou contrato quebrado; falhar explicitamente facilita diagnóstico.

  2. Qual valor é falsy em JavaScript?

    • A) '0'
    • B) []
    • C) 0
    • D) [0]
    Ver resposta

    Resposta correta: C) 0

    Zero numérico é falsy; string '0' é truthy.

  3. Liste quatro casos de teste para transferir() incluindo um de limite.

    Ver resposta

    Exemplos: transferência válida; saldo insuficiente; valor zero; mesma conta origem/destino; valor exatamente igual ao saldo (limite).