<h2>Tipos Primitivos: A Base de Tudo</h2>
<p>Em JavaScript, existem sete tipos primitivos: <code>string</code>, <code>number</code>, <code>boolean</code>, <code>null</code>, <code>undefined</code>, <code>symbol</code> e <code>bigint</code>. Eles são imutáveis e armazenados diretamente na memória, o que os torna eficientes para operações básicas. Quando você trabalha em produção, entender como esses tipos se comportam é crucial para evitar bugs sutis.</p>
<pre><code class="language-javascript">// Exemplos de tipos primitivos
const nome = "João"; // string
const idade = 30; // number
const ativo = true; // boolean
const vazio = null; // null (ausência intencional)
const naoDefinido = undefined; // undefined (não foi atribuído)
const id = Symbol('user'); // symbol (único e imutável)
const grandeNumero = 900719925474099n; // bigint
// Verificar tipos com typeof
console.log(typeof nome); // "string"
console.log(typeof idade); // "number"
console.log(typeof ativo); // "boolean"
console.log(typeof null); // "object" (bug histórico do JS!)
console.log(typeof naoDefinido); // "undefined"</code></pre>
<p>Um erro comum em produção é confundir <code>null</code> com <code>undefined</code>. Use <code>null</code> quando você <strong>intencionalmente</strong> quer representar ausência, e <code>undefined</code> aparece quando uma variável não foi atribuída ou uma função não retorna nada. Para verificar com segurança se algo é nulo, prefira <code>valor === null || valor === undefined</code> ou use o operador nullish coalescing (<code>??</code>).</p>
<h2>Objetos e Referências: Comportamento em Memória</h2>
<p>Diferente dos primitivos, objetos são tipos de referência. Eles ocupam mais memória e são armazenados como referências, não valores diretos. Em aplicações grandes, isso afeta performance e pode gerar comportamentos inesperados se não for bem compreendido.</p>
<pre><code class="language-javascript">// Primitivo: cópia por valor
let a = 10;
let b = a;
b = 20;
console.log(a); // 10 (não foi afetado)
// Objeto: cópia por referência
const usuario1 = { nome: "Ana", idade: 28 };
const usuario2 = usuario1;
usuario2.idade = 29;
console.log(usuario1.idade); // 29 (ambos apontam para o mesmo objeto!)
// Para copiar objetos com segurança, use spread operator
const usuario3 = { ...usuario1 };
usuario3.idade = 25;
console.log(usuario1.idade); // 29 (agora sim, são independentes)
// Arrays também são objetos
const numeros = [1, 2, 3];
const copia = [...numeros]; // cópia segura
copia[0] = 999;
console.log(numeros[0]); // 1 (seguro)</code></pre>
<p>Em produção, essa diferença causa problemas reais. Se você passa um objeto para uma função e a função o modifica, o original também muda. Para evitar isso, sempre faça cópias profundas quando necessário: use <code>JSON.parse(JSON.stringify(obj))</code> para casos simples ou bibliotecas como <code>lodash.clonedeep()</code> para estruturas complexas.</p>
<h2>Coerção de Tipos: O Perigo Invisível</h2>
<p>A coerção de tipos é quando JavaScript converte automaticamente um tipo em outro. É poderosa, mas perigosa em produção se não for controlada. O JavaScript faz isso em comparações (<code>==</code>), operações aritméticas e contextos lógicos.</p>
<pre><code class="language-javascript">// Comparação solta (==) causa coerção
console.log(0 == false); // true (ambos são "falsy")
console.log("5" == 5); // true (string convertida para number)
console.log(null == undefined); // true (coerção estranha!)
// Comparação estrita (===) NÃO causa coerção
console.log(0 === false); // false
console.log("5" === 5); // false
console.log(null === undefined); // false
// Operações aritméticas forçam coerção
console.log("10" - "5"); // 5 (strings convertidas)
console.log("10" + 5); // "105" (concatenação, não soma!)
console.log(true + 1); // 2 (true vira 1)
// Valores "falsy" em JavaScript
const falsy = [false, 0, "", null, undefined, NaN];
falsy.forEach(val => {
if (!val) console.log(${val} é falsy);
});
// Conversão explícita é melhor para produção
const entrada = "42";
const numero = Number(entrada); // 42
const string = String(100); // "100"
const booleano = Boolean("texto"); // true</code></pre>
<h3>Boas Práticas com Coerção</h3>
<p><strong>Sempre use <code>===</code> em vez de <code>==</code></strong> — essa é a regra de ouro. Ferramentas como ESLint forçam isso automaticamente. Converta tipos explicitamente quando necessário e documente a razão. Isso torna o código mais seguro e facilita manutenção futura por outros desenvolvedores.</p>
<h2>Tipos em Produção: Aplicação Prática</h2>
<p>Um exemplo real: ao processar dados de uma API, você recebe strings que precisam virar números. Se usar <code>==</code> para comparar, pode levar horas debugando comportamentos estranhos.</p>
<pre><code class="language-javascript"></code></pre>
<h2>Conclusão</h2>
<p>Os tipos em JavaScript definem como seu código se comporta em produção. Primeiro, domine os <strong>sete tipos primitivos</strong> e quando usar <code>null</code> versus <code>undefined</code>. Segundo, entenda que <strong>objetos são referências</strong>, não cópias, e implemente cópias seguras quando necessário. Terceiro, <strong>evite coerção implícita</strong> usando <code>===</code> e conversões explícitas — isso previne bugs sutis que custam caro em produção. Aplique estas práticas desde o início e seu código será mais confiável e manutenível.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures" target="_blank" rel="noopener noreferrer">MDN Web Docs: JavaScript Data Types</a></li>
<li><a href="https://tc39.es/ecma262/#sec-ecmascript-language-types" target="_blank" rel="noopener noreferrer">ECMAScript Specification: Types</a></li>
<li><a href="https://github.com/getify/You-Dont-Know-JS/tree/2nd-ed/types-grammar" target="_blank" rel="noopener noreferrer">You Don't Know JS: Types & Grammar</a></li>
<li><a href="https://javascript.info/types" target="_blank" rel="noopener noreferrer">JavaScript.info: Data Types</a></li>
<li><a href="https://eslint.org/docs/rules/eqeqeq" target="_blank" rel="noopener noreferrer">ESLint Rules: eqeqeq</a></li>
</ul>