Tipos de Dados em JavaScript: Um Guia Detalhado

JavaScript suporta oito tipos de dados fundamentais: Undefined, Null, Boolean, Number, String, Object, Symbol e BigInt.

Tipos de Dados Primitivos (Básicos)

  1. String: Representa dados textuais, delimitados por aspas simples (') ou duplas ("). Suporta caracteres de escape (como \n para nova linha) e template literals (introduzidos no ES6).
  2. Number: Engloba números inteiros, de ponto flutuante e valores especiais como Infinity, -Infinity e NaN (Not a Number). JavaScript não distingue entre inteiros e decimais; todos são armazenados como números de ponto flutuante de 64 bits.
  3. Boolean: Possui apenas dois valores: true e false, comumente utilizados em estruturas de controle de fluxo.
  4. Null: Representa um valor intencionalmente nulo ou vazio. É frequentemente usado para indicar a ausência explícita de um valor de objeto. O operador typeof null retorna "object", uma peculiaridade histórica da linguagem.
  5. Undefined: Indica que uma variável foi declarada, mas ainda não recebeu um valor, ou que um atributo de objeto não existe. É o valor padrão para variáveis não inicializadas e propriedades ausentes.
  6. Symbol (ES6+): Um tipo de dado único e imutável, usado principalmente como identificador exclusivo para propriedades de objetos, prevenindo colisões de nomes.
  7. BigInt (ES2020+): Permite representar e manipular números inteiros que excedem o limite de precisão do tipo Number. Números BigInt são denotados por um sufixo n (ex: 123n).

Tipos de Dados de Referência (Objetos)

  1. Object: Uma coleção de pares chave-valor, onde os valores podem ser de qualquer tipo de dado, inclusive outros objetos. ```

    let exemploPessoa = { nome: "Alice", idade: 25 };

  2. Array: Uma coleção ordenada de elementos, que podem ser de qualquer tipo. Os elementos são acessados por índice e os arrays possuem tamanho dinâmico. ```

    let listaExemplo = [1, "dois", true];

  3. Function: Um bloco de código executável, essencialmente um objeto "chamável". ```

    function saudacao(nome) { return Olá, ${nome}!; }

  4. Outros Objetos Embutidos: Incluem Date (para datas e horas), RegExp (para expressões regulares), e estruturas de dados introduzidas no ES6 como Map e Set.

Características e Operações com Tipos

  • Tipagem Dinâmica: JavaScript é uma linguagem de tipagem dinâmica e fraca. O tipo de uma variável pode mudar durante a execução do programa. ```

    let valor = 100; // É do tipo Number valor = "Texto"; // Agora é do tipo String

  • Verificação de Tipo:

    • typeof: Retorna uma string indicando o tipo do operando (ex: typeof "texto" resulta em "string"). No entanto, typeof null retorna "object".
    • instanceof: Verifica se um objeto é uma instância de uma determinada classe ou construtor (ex: [ ] instanceof Array resulta em true).
    • Array.isArray(): Um método específico e confiável para verificar se um valor é um array.
  • Conversão de Tipos:

    • Implícita: Ocorre automaticamente em certas operações (ex: 5 + "10" resulta em "510", onde o número é convertido para string).
    • Explícita: Realizada usando funções como Number(), String(), Boolean(), etc.

Considerações Importantes

  • Gerenciamento de Memória para Tipos de Referência: Variáveis de tipos de objeto armazenam referências (endereços de memória). Ao copiar tais variáveis, é crucial distinguir entre cópias rasas (shallow copy) e profundas (deep copy).

  • Diferença entre null e undefined: null representa a ausência intencional de valor, enquanto undefined indica que um valor ainda não foi atribuído.

  • Unicidade dos Symbol: Cada Symbol gerado é unicamente diferente, mesmo que possua a mesma descrição. Isso os torna ideais para evitar conflitos em nomes de propriedades. Ex: Symbol('id') !== Symbol('id').

  • Uso de BigInt: Números BigInt requerem o sufixo n e não podem ser misturados diretamente em operações com números do tipo Number.

  • Conversões de Tipo e Comportamento Inesperado: Certas conversões de tipo em JavaScript podem levar a resultados surpreendentes. ```

    console.log([] + []); // Retorna "" (string vazia) console.log([] + {}); // Retorna "[object Object]" console.log({} + []); // Pode retornar 0 em alguns ambientes

    
    

Symbol e BigInt: Tipos Modernos

Symbol e BigInt são adições importantes ao conjunto de tipos de dados do JavaScript, introduzidas nas especificações ECMAScript 2015 (ES6) e 2020, respectivamente.

  • Symbol: Pense em um Symbol como uma chave única e intransferível. Sua principal aplicação é criar identificadores exclusivos para propriedades de objetos, garantindo que não haja sobreposição de nomes, o que é particularmente útil em grandes projetos ou ao usar bibliotecas de terceiros.
  • BigInt: Projetado para lidar com inteiros de magnitude extremamente grande, que ultrapassam o limite seguro do tipo Number (Number.MAX_SAFE_INTEGER). BigInt oferece precisão garantida para cálculos com números astronômicos ou dados financeiros de alta precisão.

Tipos Primitivos vs. Compostos (Objetos)

Os tipos de dados em JavaScript podem ser categorizados em primitivos e compostos (ou de referência).

  • Tipos Primitivos: São os blocos de construção básicos de dados. Incluem Undefined, Null, Boolean, Number, String, Symbol e BigInt. Eles são imutáveis e armazenados diretamente na memória de "pilha" (stack), permitindo acesso rápido.
  • Tipos Compostos (Objetos): O principal tipo composto é o Object, que abrange objetos literais, arrays, funções e instâncias de classes. Eles são mutáveis e armazenados na memória de "heap". Variáveis de objeto contêm referências para os dados na heap, e não os dados em si.

Mecanismos de Verificação de Tipo

  • typeof: Retorna uma string representando o tipo. Funciona bem para a maioria dos primitivos, mas tem a conhecida exceção de null (retorna "object") e trata arrays como "object". ```

    console.log(typeof 42); // "number" console.log(typeof "Olá"); // "string" console.log(typeof true); // "boolean" console.log(typeof Symbol()); // "symbol" console.log(typeof 42n); // "bigint" console.log(typeof null); // "object" (peculiaridade) console.log(typeof {}); // "object" console.log(typeof []); // "object" console.log(typeof function(){});// "function"

  • instanceof: Avalia se um objeto é uma instância de um construtor específico. Útil para tipos de referência. Retorna false para tipos primitivos, a menos que tenham sido criados com o construtor (ex: new Number(42)). ```

    console.log([] instanceof Array); // true console.log({} instanceof Object); // true console.log(new Date() instanceof Date); // true console.log(42 instanceof Number); // false console.log(new Number(42) instanceof Number); // true

  • constructor: Pode ser usado para verificar o construtor de um valor. No entanto, falha para null e undefined e pode apresentar problemas com valores primitivos literais em certas situações. ```

    console.log((42).constructor === Number); // true console.log("Olá".constructor === String); // true console.log([].constructor === Array); // true console.log(({}).constructor === Object); // true // console.log(null.constructor === Object); // Erro!

  • Object.prototype.toString.call(): Um método robusto que retorna uma string formatada indicando o tipo interno do objeto. É uma das formas mais confiáveis de identificar tipos, incluindo null e undefined. ```

    console.log(Object.prototype.toString.call(42)); // "[object Number]" console.log(Object.prototype.toString.call("Olá")); // "[object String]" console.log(Object.prototype.toString.call(true)); // "[object Boolean]" console.log(Object.prototype.toString.call(null)); // "[object Null]" console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]" console.log(Object.prototype.toString.call([])); // "[object Array]" console.log(Object.prototype.toString.call({})); // "[object Object]" console.log(Object.prototype.toString.call(function(){})); // "[object Function]"

    
    

Pontos de Atenção

  1. Detecção de null: typeof null retorna "object" devido a uma decisão de design histórica. Para verificar corretamente se um valor é null, use a igualdade estrita: valor === null.

  2. Objetos Envolventes para Primitivos: JavaScript cria automaticamente objetos "envolventes" temporários para tipos primitivos quando métodos são chamados neles (ex: "hello".toUpperCase()).

  3. Unicidade de Symbol: A característica fundamental dos Symbols é sua unicidade intrínseca. Mesmo descrições idênticas geram Symbols distintos: Symbol('foo') !== Symbol('foo').

  4. Uso de BigInt: Lembre-se de anexar o sufixo n a números literais para criar BigInts e evite misturar BigInt com Number em operações aritméticas para prevenir erros.

  5. Conversões de Tipo e Comportamentos: Esteja ciente de como JavaScript lida com conversões implícitas, pois elas podem gerar resultados inesperados. ```

    console.log([] + []); // "" console.log([] + {}); // "[object Object]" console.log({} + []); // 0 (comportamento pode variar)

Tags: javascript tipos de dados primitivos objetos symbol

Publicado em 6-17 02:33