LUCIO PATROCINIO
LUCIO PATROCINIO16/07/2025 10:52
Compartilhe

Erros comuns no uso de condicionais em JavaScript

    Introdução

    Seja qual for a linguagem de programação, as expressões condicionais assumem um papel importante no controle do fluxo das instruções de comando. No caso do JavaScript há um conjunto básico de instruções condicionais similar ao de outras linguagens (if-else, switch, etc.).

    A utilização dessas instruções condicionais costuma ser acompanhada por erros comuns de programação, tanto de sintaxe quanto de semântica. Neste artigo busco ilustrar algumas desses erros, lembrando que esta lista não tenta exaurir todas as situações possíveis e no processo auxiliar a quem está começando a codificar.

    Situação-problema 1: Atribuição (=) em vez de Comparação (== ou ===)

    Muitas linguagens utilizam o sinal de "=" (igual) para realizar atribuição de valor a uma variável ou constante, enquanto outros operadores são utilizados para fazer comparação entre valores. No caso do JavaScript, a comparação entre valores é feita pelo duplo sinal de igual (==), enquanto o sinal triplo de igual (===) compara não apenas o valor, mas também o tipo dos dados. É muito comum que o codificador por pressão ou urgência em entregar o programa faça confusão entre esses os operadores de comparação (== ou ===) e o de atribuição (=).

    No trecho de código abaixo, a variável "valor" recebe inicialmente o valor numérico 10. Entretanto, na cláusula de condição do IF, utiliza-se "(valor = 5)" para verificar a igualdade entre 10 e 5. Como foi utilizado apenas um sinal de igual, isso resultou na atribuição do 5 a variável "valor". A instrução de atribuição é considerada "verdadeira", fazendo com que a instrução dentro do IF sempre seja executada. Mas o conteúdo da variável "valor" mudou de 10 para 5.

    let valor = 10;
    if (valor = 5) { // Erro: isso atribui 5 a 'valor' e depois avalia '5' como verdadeiro
    console.log("Isso sempre será executado!");
    }
    console.log("O valor agora é: ", valor); // Saída: 5
    

    Neste caso, não ocorre nenhuma mensagem de erro durante a execução desse trecho de código. Como isso poderia ser corrigido? Trocando o sinal de "=" pelo de "==" ou "===". O operador "===" é preferível por ser mais rigoroso e evitar a conversão de tipos durante a realização da comparação. O código corrigido ficaria assim:

    let valor = 10;
    if (valor === 5) { // Correto: compara se 'valor' é estritamente igual a 5
    console.log("Isso só será executado se valor for 5.");
    }
    console.log("O valor ainda é: ", valor); // Saída: 10
    

    Situação-Problema 2: Ausência de Chaves {} em Blocos de Código

    O abrir e fechar chave { } é utilizado para agrupar instruções em blocos que devem ser executados juntos. Quando um if, else, for ou while tem apenas uma única instrução logo após a condicional, as chaves são opcionais. No entanto, omiti-las pode levar a bugs sutis se você adicionar mais instruções posteriormente. O mais interessante é que na maioria dos casos, este erro não irá resultar em mensagem de erro ou falha do programa. Vejamos o exemplo abaixo:

    let pontuacao = 100;
    if (pontuacao > 90)
    console.log("Excelente!");
    console.log("Parabéns!"); // Este console.log *não* faz parte do if
    

    Observe na instrução acima que, provavelmente, o autor queria que as duas instruções "console.log" fossem executadas quando a condição do IF fosse verdadeira. Entretanto, apenas o primeiro "console.log" é parte do IF. O segundo sempre é executado após o término da instrução IF, e portanto, não depende dela. A correção neste caso é simples. Basta colocar as chaves cercando o bloco de instruções que faz parte do IF. Assim:

    let pontuacao = 100;
    if (pontuacao > 90) {
    console.log("Excelente!");
    console.log("Parabéns!"); // Agora ambos fazem parte do if
    }
    

    Situação-Problema 3: Ordem Incorreta de else if com Faixas de Valores

    Este erro comum para quem tem que trabalhar com classificação em faixas de valores (ou ranges). Muitas vezes, quando não se projeta adequadamente os intervalos de valores, pode surgir um valor que fica fora de todos os intervalos previstos no código, e assim, resultando em um erro de lógica. Como muitos erros de lógica, geralmente não resulta em mensagens de erro ou falha. Veja o código-exemplo a seguir:

    let idade = 25;
    if (idade < 18) {
    console.log("Menor de idade");
    } else if (idade < 60) { // Esta condição pega idades entre 18 e 59
    console.log("Adulto");
    } else if (idade < 30) { // Erro: esta condição nunca será alcançada para idades < 30 e >= 18
    console.log("Jovem adulto");
    } else {
    console.log("Idoso");
    }
    

    Observamos que a instrução "else if (idade < 30)" está na posição incorreta, pois o comando anterior, "else if (idade < 60) ", já inclui o intervalo de idades menores que 30, e portanto, qualquer idade menor que 30 irá entrar neste "else if" e nunca no próximo. A solução é inverter os dois else-ifs. Assim:

    let idade = 25;
    if (idade < 18) {
    console.log("Menor de idade");
    } else if (idade < 30) { // Agora esta é verificada para idades >= 18
    console.log("Jovem adulto");
    } else if (idade < 60) { // Agora esta é verificada para idades >= 30
    console.log("Adulto");
    } else {
    console.log("Idoso");
    } 
    

    Neste caso:

    • "if (idade < 18)" - irá pegar a faixa de idades até 17 anos (no caso de número inteiro) de idade.
    • "else if (idade < 30) - pega o intervalo de 18 (incluso) até 29 anos de idade.
    • "else if (idade < 60) - pega o intervalo de 30 (incluso) até 59 anos de idade.
    • "else" - irá cobrir as idades de 60 (incluso) para cima.

    Situação-Problema 4: switch sem break (Fall-through)

    A instrução "break" encerra o CASE e pula para fora do SWITCH. A falta do break não é necessariamente um erro, mas depende da intenção do programador. Se cada CASE precisa ser estanque, ou seja se apenas bloco de comandos deve ser executado, o "break" precisa estar presente no final do bloco de instruções. Caso contrário, a programa continua executando os cases a seguir. Veja o exemplo abaixo:

    let dia = "quarta";
    switch (dia) {
    case "segunda":
      console.log("Início da semana");
    case "terca":
      console.log("Meio da semana");
    case "quarta":
      console.log("Quase lá!"); // Será executado
    case "quinta":
      console.log("Fim de semana chegando"); // Também será executado!
      break;
    default:
      console.log("Dia inválido");
    }
    // Saída: "Quase lá!"
    //         "Fim de semana chegando"
    

    Sem break, o JavaScript "cai" para o próximo case e executa seu código, e assim por diante, até encontrar um break ou o final do switch. Se você espera que apenas um case seja executado, isso causará comportamento inesperado. Neste caso, o programa apresentou duas mensagens quando deveria ter apresentado apenas uma ("Quase lá!"). A correção desse problema consiste em acrescentar o "break" ao final de cada case. Assim:

    let dia = "quarta";
    switch (dia) {
    case "segunda":
      console.log("Início da semana");
      break;
    case "terca":
      console.log("Meio da semana");
      break;
    case "quarta":
      console.log("Quase lá!");
      break; // Adicionado break
    case "quinta":
      console.log("Fim de semana chegando");
      break;
    default:
      console.log("Dia inválido");
    }
    // Saída: "Quase lá!"
    

    Situação-Problema 5: Utilização de igualdade e desigualdade abstrata (== ou !=)

    JavaScript é uma linguagem de tipagem fraca e dinâmica. Isso significa que ela pode, em certas situações, tentar converter (ou "coagir") valores de um tipo para outro automaticamente para que uma operação (como uma comparação) possa ser realizada. É aqui que == e != se diferenciam de === e !==.

    Vejamos como exemplo, a comparação entre número e string. Nesta situação, "==" e "!=" tentam converter os tipos de cada variável para um tipo de dado comum antes de fazer a comparação.

    const numero = 5;
    const texto = "5";
    
    
    if (numero == texto) { // true, porque "5" é coagido para o número 5
    console.log("Número e texto são iguais com `==`");
    }
    
    
    if (0 == false) { // true, porque false é coagido para 0
    console.log("0 e false são iguais com `==`");
    }
    
    
    if ("" == 0) { // true, porque "" é coagido para 0
    console.log("String vazia e 0 são iguais com `==`");
    }
    
    
    if (null == undefined) { // true, caso especial da linguagem
    console.log("null e undefined são iguais com `==`");
    } 
    

    Podemos ver que o primeiro IF é considerado verdadeiro, mesmo sabendo que estamos comparando um número e uma cadeia de caracteres (string). O mesmo pode ser dito sobre os demais comandos condicionais, o interpretador tenta converter o valores comparados para um tipo comum. No caso do código acima, ele é bem sucedido em todas as conversões de tipo, resultando em VERDADEIRO para todos os condicionais. Nem sempre é isso que queremos que aconteça. Para corrigir esse problema, usamos os operadores estritos de comparação (=== e !==). Assim:

    const numero = 5;
    const texto = "5";
    
    
    if (numero === texto) { // false, porque number !== string
    console.log("Nunca será executado com `===`");
    } else {
    console.log("Número e texto não são iguais com `===` (tipos diferentes)");
    }
    
    
    if (0 === false) { // false, porque number !== boolean
    console.log("Nunca será executado com `===`");
    } else {
    console.log("0 e false não são iguais com `===` (tipos diferentes)");
    }
    
    
    if ("" === 0) { // false, porque string !== number
    console.log("Nunca será executado com `===`");
    } else {
    console.log("String vazia e 0 não são iguais com `===` (tipos diferentes)");
    }
    
    
    if (null === undefined) { // false, porque null !== undefined
    console.log("Nunca será executado com `===`");
    } else {
    console.log("null e undefined não são iguais com `===` (tipos diferentes)");
    }
    

    Conclusão: De forma geral, os comparadores estritos são preferíveis pois tornam o resultado da comparação mais previsível, acarretando menos bugs e mais clareza de código. O único cenário comum em que == é intencionalmente usado é para verificar se um valor é null ou undefined.

    Compartilhe
    Comentários (1)
    DIO Community
    DIO Community - 16/07/2025 13:40

    Lucio, sua análise sobre os erros mais comuns no uso de condicionais em JavaScript é extremamente valiosa para desenvolvedores em qualquer nível. Você destaca de forma clara e didática problemas que frequentemente passam despercebidos, como a confusão entre atribuição e comparação, a omissão de chaves em blocos de código, e a ordem incorreta de condições em estruturas como else if.

    O ponto sobre o uso de == vs. === é crucial. Como JavaScript é uma linguagem de tipagem dinâmica, muitos desenvolvedores iniciantes acabam caindo na armadilha de comparações imprecisas, o que pode gerar bugs difíceis de detectar.

    Você acredita que a adoção de boas práticas de codificação, como o uso de === ao invés de ==, pode ser considerada uma "soft skill" para desenvolvedores, além de ser um simples detalhe técnico?