
Junior Alves
Senior Developer
Foto: Unsplash
Atualizado: 18 de novembro de 2025 às 08:01
Leitura: 8 minutos de leitura
Criado: 15 de novembro de 2025
5 mitos do JS que você acreditou por tempo demais
As principais "pegadinhas" que caem em entrevistas técnicas
Faaala dev, blz? Se você já passou algum tempo com Javascript, provavelmente já se deparou com uma situação que te fez parar, coçar a cabeça e perguntar: "mas que diabos está acontecendo aqui?". Talvez tenha sido uma comparação que retornou true quando você jurava que deveria ser false, ou um this que parecia ter vida própria.
A boa notícia é que, na maioria das vezes, esses comportamentos "estranhos" não são bugs na linguagem. São características e, sejamos honestos, um tanto peculiares, que são frequentemente mal compreendidas. Muitas dessas "loucuras" são, na verdade, mitos perpetuados por uma compreensão superficial do que realmente acontece nos bastidores da engine Javascript.
Hoje, vamos entender e desmistificar os 5 maiores mitos do JS!
Mito 1: A Coerção de tipos é imprevisível
Vamos começar com um clássico, o tipo de código que gera memes e já gerou longas threads no Stack Overflow:
[] == ![] // retorna trueSe sua primeira reação foi "WTF?", você não está sozinho. Parece um absurdo, mas a verdade é que esse resultado não é aleatório. O Javascript possui regras bem definidas para lidar com tipos diferentes em uma comparação, e o que vemos aqui é um processo chamado coerção de tipos.
É importante distinguir entre conversão explícita (quando usamos Number('42'), por exemplo) e coerção implícita, que é o que o Javascript faz automaticamente nos bastidores. O operador == aciona essa coerção seguindo o algoritmo Abstract Equality Comparison (Comparação de Igualdade Abstrata), especificado no padrão ECMAScript. Em contraste, o operador === segue o algoritmo Strict Equality Comparison (Comparação de Igualdade Estrita), que não realiza coerção de tipos e é quase sempre a escolha mais segura.
Para entender o [] == ![], precisamos analisar o passo a passo:
- O operador de negação (!) tem precedência. Para avaliá-lo, o Javascript converte o valor para um booleano. Quase tudo em Javascript é "truthy" (verdadeiro), exceto por uma pequena lista de valores "falsy":
false,null,undefined,0,-0,NaNe a string vazia"". Como um array [] é um objeto, ele é "truthy". Portanto,![]resulta emfalse. A expressão se torna:[] == false. - O algoritmo de Comparação de Igualdade Abstrata (==) diz que se um dos lados é um booleano, ele é convertido para um número. false vira 0. A expressão agora é:
[] == 0. - O algoritmo continua: se um lado é um objeto e o outro é um número, o objeto é convertido para um primitivo. Um array vazio [] é convertido para a string vazia "". A expressão fica:
"" == 0. - Agora, se um lado é uma string e o outro é um número, a string é convertida para um número. A string vazia "" se torna 0.
- Finalmente, a comparação é
0 == 0, que retornatrue.
Viu? Não é magia, é um algoritmo lógico. Peculiar, com certeza, mas totalmente previsível. O verdadeiro truque é usar === e evitar a maior parte dessa confusão.
Mito 2: Javascript só tem escopo de função
Este mito tem um fundo de verdade histórica. Na "era de ouro do var", o Javascript realmente só tinha escopo de função e escopo global. Isso levava a alguns comportamentos contraintuitivos, especialmente em laços de repetição com código assíncrono.
O exemplo clássico é o for loop com setTimeout:
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 100);
}
// Saída: 3, 3, 3Por que isso acontece? Porque var não tem escopo de bloco. Existe apenas uma variável i compartilhada por todas as iterações do loop e por todas as funções de callback do setTimeout. Quando os callbacks finalmente executam, o loop já terminou e o valor de i é 3.
Com a chegada do ES6 (ECMAScript 2015), fomos apresentados a let e const, que trouxeram o tão esperado escopo de bloco para o Javascript. Veja como o problema é resolvido de forma elegante:
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 100);
}
// Saída: 0, 1, 2Usando let, uma nova ligação para a variável i é criada em cada iteração do loop. Cada callback do setTimeout captura uma versão diferente de i, com o valor correspondente àquela iteração específica. O Javascript moderno é, sem dúvida, muito mais robusto e previsível em relação ao escopo.
Mito 3: const torna um objeto imutável
Este é um dos mitos que mais pega desenvolvedores iniciantes. A palavra-chave const soa como se o valor que ela guarda não pudesse ser alterado, mas o segredo está em entender a diferença entre reatribuição e mutação.
const cria uma ligação de variável somente leitura, o que significa que a variável não pode ser reatribuída para apontar para um novo valor. No entanto, const não faz nada para impedir a mutação do valor que ela contém. Se esse valor for um objeto ou um array, seu conteúdo interno pode ser modificado livremente.
Veja na prática:
const user = {
name: 'Ada Lovelace',
language: 'Javascript'
};
// Isso é perfeitamente válido (mutação):
user.language = 'Assembly';
console.log(user.language); // 'Assembly'
// Tentar reatribuir a variável gera um erro:
user = { name: 'Grace Hopper' }; // TypeError: Assignment to constant variable.A variável user não pode receber um objeto totalmente novo, mas suas propriedades podem ser alteradas.
Se você realmente precisa de imutabilidade, pode usar Object.freeze(). Este método impede que novas propriedades sejam adicionadas e que as existentes sejam removidas ou alteradas, resultando em imutabilidade superficial. É "superficial" porque ele não congela objetos aninhados dentro do objeto principal; para isso, seria necessária uma função recursiva.
const frozenUser = { name: 'Hedy Lamarr', address: { city: 'Vienna' } };
Object.freeze(frozenUser);
frozenUser.name = 'Heidi'; // A alteração falha silenciosamente.
frozenUser.address.city = 'Los Angeles'; // Isto funciona, pois o objeto aninhado não foi congelado.
console.log(frozenUser.name); // 'Hedy Lamarr'
console.log(frozenUser.address.city); // 'Los Angeles'Mito 4: O valor de this depende de onde a função foi escrita
O this é uma das fontes mais comuns de confusão em Javascript. Muitos acreditam que seu valor é definido no momento em que a função é criada (escopo léxico), mas isso só é verdade para as arrow functions. Para funções tradicionais, o valor de this é uma ligação de tempo de execução (runtime binding), determinada inteiramente por como a função é invocada — o seu call-site.
Vamos ver três cenários comuns:
- Invocação Simples: Quando uma função é chamada diretamente, sem um objeto de contexto.
- Invocação como Método: Quando uma função é chamada como uma propriedade de um objeto.
- Arrow Function: Elas não possuem seu próprio this. Em vez disso, capturam o this do escopo léxico circundante onde foram criadas, resolvendo problemas clássicos de contexto.
Mito 5: O operador % é módulo
Para a maioria dos casos envolvendo números positivos, os operadores de resto e módulo se comportam de forma idêntica, o que faz com que esse mito passe despercebido. No entanto, a diferença se torna clara quando lidamos com números negativos.
Em Javascript (e em muitas linguagens da família C), o operador % é, na verdade, o operador de resto (remainder), não de módulo (modulo). A diferença fundamental está em como o sinal do resultado é determinado:
- O operador de resto (%) sempre assume o sinal do dividendo (o primeiro número).
- Uma operação de módulo verdadeira sempre assume o sinal do divisor (o segundo número).
Veja a diferença na prática:
// Operador de Resto em Javascript
console.log(-10 % 3); // -1 (o sinal do dividendo, -10, é mantido)
// Uma operação de Módulo verdadeira
// -10 mod 3 = 2 (o resultado não é -1)No dia a dia, essa distinção pode não parecer importante. Mas para algoritmos matemáticos mais complexos, como em criptografia ou certas estruturas de dados, entender a diferença entre resto e módulo é absolutamente crucial.
Pratique para fixar 🎉
Conclusão
Javascript é uma linguagem cheia de nuances, mas raramente é ilógica. Seja a lógica previsível por trás da coerção de tipos, a natureza dinâmica do this ou a diferença sutil entre resto e módulo, o Javascript opera com consistência. Dominar essas regras é o que transforma comportamentos "estranhos" em ferramentas poderosas.
Compreender a coerção de tipos, o escopo, o this, const e até os operadores matemáticos em profundidade é o que separa um desenvolvedor júnior de um sênior.
E você, qual mito do Javascript já te pegou de surpresa? Deixe sua história nos comentários!
💡 Quer aprender mais sobre Next.js?
Confira meus cursos práticos e aprenda a criar aplicações profissionais do zero.
Ver CursosCurtiu? Compartilhe esse post: