Vamos explorar cada tipo primitivo em detalhes.
String
Uma string representa dados de texto: uma sequência de caracteres.
snippetJavaScript
// Três formas de criar stringslet single = 'Hello'; // Aspas simpleslet double = "World"; // Aspas duplaslet backtick = `Hello World`; // Template literal (ES6)
Template Literals (ainda são strings!)
Template literals (crases) não são um tipo separado. São apenas uma sintaxe mais poderosa para criar strings. O resultado continua sendo uma string primitiva:
snippetJavaScript
let name = "Alice";let age = 25; // Interpolação de string — embute expressõeslet greeting = `Olá, ${name}! Você tem ${age} anos.`;console.log(greeting); // "Olá, Alice! Você tem 25 anos."console.log(typeof greeting); // "string" — é só uma string! // Strings multilinhalet multiLine = ` Esta é a linha 1 Esta é a linha 2`;console.log(typeof multiLine); // "string"
Strings são imutáveis
Você não pode alterar caracteres individuais em uma string:
snippetJavaScript
let str = "hello";str[0] = "H"; // Não faz nada! Sem erro, mas sem mudançaconsole.log(str); // Ainda "hello" // Para "alterar" uma string, crie uma novastr = "H" + str.slice(1);console.log(str); // "Hello"
Métodos como toUpperCase(), slice(), replace() sempre retornam novas strings. Eles nunca modificam a original.
Number
O JavaScript tem apenas um tipo numérico para inteiros e decimais. Todos os números são armazenados como ponto flutuante de 64 bits (padrão IEEE 754).
snippetJavaScript
let integer = 42; // Inteirolet decimal = 3.14; // Decimallet negative = -10; // Negativolet scientific = 2.5e6; // 2.500.000 (notação científica)
Valores numéricos especiais
snippetJavaScript
console.log(1 / 0); // Infinityconsole.log(-1 / 0); // -Infinityconsole.log("hello" * 2); // NaN (Not a Number)
O JavaScript tem valores especiais: Infinity para valores grandes demais para representar, e NaN (Not a Number) para operações matemáticas inválidas.
O famoso problema de ponto flutuante
snippetJavaScript
console.log(0.1 + 0.2); // 0.30000000000000004console.log(0.1 + 0.2 === 0.3); // false! Bem-vindo ao JavaScript!
Isso não é um bug do JavaScript — segue o padrão IEEE 754 de ponto flutuante de dupla precisão usado por praticamente todas as linguagens modernas. O decimal 0.1 não pode ser representado perfeitamente em binário.
Trabalhando com dinheiro? Nunca use ponto flutuante para cálculos! Armazene valores em centavos como inteiros e use Intl.NumberFormat para exibição.
snippetJavaScript
// Ruim: erros de ponto flutuante nos cálculoslet price = 0.1 + 0.2; // 0.30000000000000004 // Bom: calcule em centavos, formate para exibiçãolet priceInCents = 10 + 20; // 30 (cálculo preciso!) const formatter = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL',});console.log(formatter.format(priceInCents / 100)); // "R$ 0,30"
Intl.NumberFormat é nativo do JavaScript. Sem bibliotecas externas! Ele cuida de símbolos de moeda, separadores decimais e formatação por locale automaticamente.
Faixa segura de inteiros
snippetJavaScript
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991 (2^53 - 1)console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
Number.MAX_SAFE_INTEGER é o maior inteiro que pode ser representado com segurança. Além dessa faixa, a precisão se perde:
snippetJavaScript
console.log(9007199254740992 === 9007199254740993); // true! (errado!)
Para inteiros maiores, use BigInt.
BigInt
BigInt (ES2020) representa inteiros maiores que Number.MAX_SAFE_INTEGER.
snippetJavaScript
let big = 9007199254740993n;let alsoBig = BigInt("9007199254740993"); console.log(big + 1n); // 9007199254740994n (correto!)
Regras do BigInt
snippetJavaScript
let big = 10n;let regular = 5;// console.log(big + regular); // TypeError! console.log(big + BigInt(regular)); // 15nconsole.log(Number(big) + regular); // 15
Quando usar BigInt: criptografia, timestamps precisos, IDs de banco de dados, qualquer cálculo que exija inteiros maiores que 9 quatrilhões.
Boolean
Boolean tem exatamente dois valores: true e false.
snippetJavaScript
let isLoggedIn = true;let hasPermission = false; let isAdult = age >= 18;let isEqual = name === "Alice";
Truthy e Falsy
Em contextos booleanos (como if), todos os valores são "truthy" ou "falsy":
snippetJavaScript
// Valores falsy (só 8!)false0-00n // BigInt zero"" // String vazianullundefinedNaN // Todo o resto é truthy"hello" // truthy42 // truthy[] // truthy (array vazio!){} // truthy (objeto vazio!)
snippetJavaScript
let value = "hello";let bool = Boolean(value); // truelet shortcut = !!value; // true (truque da dupla negação)
undefined
undefined significa "nenhum valor foi atribuído". O JavaScript o usa automaticamente em várias situações:
snippetJavaScript
// 1. Declarado mas não atribuídolet x;console.log(x); // undefined // 2. Parâmetro de função ausentefunction greet(name) { console.log(name);}greet(); // 3. Função sem returnfunction doNothing() {}console.log(doNothing()); // undefined // 4. Propriedade inexistentelet person = { name: "Alice" };console.log(person.age); // undefined
Não atribua undefined explicitamente a variáveis. Use null para indicar "vazio intencional".
null
null significa "vazio intencional". Você está dizendo explicitamente: "isso não tem valor".
snippetJavaScript
let user = { name: "Alice" };user = null; // Usuário deslogou, limpando a referência function findUser(id) { return null; // Usuário não encontrado}
O famoso bug do typeof
snippetJavaScript
console.log(typeof null); // "object" — Espera, o quê?!
Sim, de verdade. É um dos quirks mais famosos do JavaScript! Um erro histórico da primeira implementação em 1995. Nunca foi corrigido porque muito código existente depende disso.
snippetJavaScript
let value = null;console.log(value === null); // true (use igualdade estrita)
Symbol
Symbol (ES6) cria identificadores únicos. Mesmo símbolos com a mesma descrição são diferentes.
snippetJavaScript
let id1 = Symbol("id");let id2 = Symbol("id"); console.log(id1 === id2); // false — sempre únicos!console.log(id1.description); // "id"
Caso de uso: chaves únicas em objetos
snippetJavaScript
const ID = Symbol("id");const user = { name: "Alice", [ID]: 12345}; console.log(user.name); // "Alice"console.log(user[ID]); // 12345console.log(Object.keys(user)); // ["name"] — ID não aparece
Well-Known Symbols
O JavaScript tem símbolos embutidos para customizar comportamento de objetos: Symbol.iterator, Symbol.toStringTag, Symbol.toPrimitive, entre outros.
Symbols são um recurso avançado. Como iniciante, foque em entender que eles existem e criam valores únicos. Você os encontrará em padrões avançados e código de bibliotecas.