Estrutura de dados do Javascript
Todas as linguagens de programação têm estruturas de dados embutidas, mas geralmente diferem de uma linguagem para outra. Este artigo tenta listar as estruturas de dados internas disponíveis em JavaScript e quais propriedades elas possuem. Estes podem ser usados para construir outras estruturas de dados. Sempre que possível, são feitas comparações com outras línguas.
Tipagem dinâmica e fraca
JavaScript é uma linguagem dinâmica com tipos dinâmicos. As variáveis em JavaScript não estão diretamente associadas a nenhum tipo de valor específico, e qualquer variável pode receber (e reatribuir) valores de todos os tipos:
let foo = 42; // foo agora é um número
foo = "bar"; // foo agora é uma string
foo = true; // foo agora é um booleano
JavaScript também é uma linguagem de tipagem fraca, o que significa que permite a conversão implícita de tipo quando uma operação envolve tipos incompatíveis, em vez de gerar erros de tipo.
const foo = 42; //foo é um número
const result = foo + "1"; // JavaScript coage foo para uma string, então ela pode ser concatenada com o outro operando
console.log(resultado); // 421
Coerções implícitas são muito convenientes, mas podem ser uma arma em potencial se os desenvolvedores não pretendem fazer a conversão ou pretendem converter na outra direção (por exemplo, string para número em vez de número para string). Para symbols e BigInts, o JavaScript desativou intencionalmente certas conversões de tipo implícito.
Tipos em JavaScript
O conjunto de tipos na linguagem JavaScript consiste em primitive values e objects.
-
Valores primitivos (dados imutáveis representados diretamente no nível mais baixo do idioma)
-
Objetos (coleções de propriedades)
Valores primitivos
Todos os tipos, exceto objetos, definem valores imutáveis (ou seja, valores que não podem ser alterados). Por exemplo, Strings são imutáveis. Referimo-nos a valores desses tipos como "valores primitivos".
Tipo Boolean
Boolean representa uma entidade lógica e pode ter dois valores: true e false. Consulte Boolean e Boolean para obter mais detalhes.
Tipo Null
O tipo Null tem exatamente um valor: null. Consulte null e Null para obter mais detalhes.
Tipo Undefined
Uma variável que não recebeu um valor tem o valor undefined. Consulte undefined e Undefined para mais detalhes.
Tipos numéricos
ECMAScript tem dois tipos numéricos integrados: Number e BigInt — junto com o valor relacionado NaN.
Tipo Number
O tipo Number é um valor IEEE 754 de formato binário de 64 bits de precisão dupla. É capaz de armazenar números de ponto flutuante positivos entre 2^-1074 (Number.MIN_VALUE) e 2^1024 (Number.MAX_VALUE), bem como números de ponto flutuante negativos entre -(2^-1074) e -(2^1024), mas só pode armazenar com segurança inteiros no intervalo -(2^53 − 1) (Number.MIN_SAFE_INTEGER) para 2^53 − 1 (Number.MAX_SAFE_INTEGER).
Nota:
Você pode verificar se um número está dentro do intervalo de inteiros seguros usando Number.isSafeInteger(). Fora do intervalo de Number.MIN_SAFE_INTEGER a Number.MAX_SAFE_INTEGER, o JavaScript não pode mais representar inteiros com segurança; eles serão representados por uma aproximação de ponto flutuante de precisão dupla.
Valores fora do intervalo ±(2^-1074 a 2^1024) são convertidos automaticamente:
- Valores positivos maiores que
Number.MAX_VALUEsão convertidos em+Infinity. - Valores positivos menores que
Number.MIN_VALUEsão convertidos em+0. - Valores negativos menores que -
Number.MAX_VALUEsão convertidos para-Infinity. - Valores negativos maiores que -
Number.MIN_VALUEsão convertidos para-0.
+Infinity e -Infinity se comportam de forma semelhante ao infinito matemático, mas com algumas pequenas diferenças; veja Number.POSITIVE_INFINITY e Number.NEGATIVE_INFINITY para detalhes.
O tipo Number tem apenas um inteiro com múltiplas representações: 0 é representado como -0 e +0 (onde 0 é um alias para +0). Na prática, quase não há diferença entre as diferentes representações; por exemplo, +0 === -0 é true. No entanto, você pode perceber isso quando divide por zero:
console.log(42 / +0); // Infinity
console.log(42 / -0); // -Infinity
Embora um número geralmente represente apenas seu valor, o JavaScript fornece operadores bitwise.
Nota: Embora os operadores bit a bit podem ser usados para representar vários valores booleanos em um único número usando mascaramento de bits, isso geralmente é considerada uma má prática. JavaScript oferece outros meios para representar um conjunto de booleanos (como uma matriz de booleanos ou um objeto com valores booleanos atribuídos a propriedades nomeadas). O mascaramento de bits também tende a tornar o código mais difícil de ler, entender e manter.
Pode ser necessário usar essas técnicas em ambientes muito restritos, como ao tentar lidar com as limitações do armazenamento local ou em casos extremos (como quando cada bit na rede conta). Esta técnica só deve ser considerada quando for a última medida que pode ser tomada para otimizar o tamanho.
Tipo BigInt
O tipo BigInt é uma primitiva numérica em JavaScript que pode representar inteiros com precisão arbitrária. Com BigInts, você pode armazenar e operar com segurança em grandes números inteiros, mesmo além do limite de números inteiros seguros.
Um BigInt é criado anexando n ao final de um inteiro ou chamando o construtor.
Você pode obter o maior valor seguro que pode ser incrementado com Numbers usando a constante Number.MAX_SAFE_INTEGER. Com a introdução do BigInts, você pode operar com números além do Number.MAX_SAFE_INTEGER.
Este exemplo demonstra, onde incrementar o Number.MAX_SAFE_INTEGER retorna o resultado esperado:
// BigInt
const x = BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
x + 1n === x + 2n; // false porque 9007199254740992n e 9007199254740993n são desiguais
// Number
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true porque ambos são 9007199254740992
Você pode usar os operadores +, *, -, ** e % com BigInts — assim como com Numbers. Um BigInt não é estritamente igual a um Number, mas é vagamente assim.
Um BigInt se comporta como um Number nos casos em que é convertido em booleano: if, ||, &&, Boolean, !.
BigInts não podem ser operados de forma intercambiável com Numbers. Em vez disso, um TypeError será lançado.
NaN
NaN ("Not a Number") é normalmente encontrado quando o resultado de uma operação aritmética não pode ser expresso como um número. É também o único valor em JavaScript que não é igual a si mesmo.
Tipo String
O tipo String do JavaScript é usado para representar dados textuais. É um conjunto de "elementos" de valores inteiros sem sinal de 16 bits. Cada elemento na String ocupa uma posição na String. O primeiro elemento está no índice 0, o próximo no índice 1 e assim por diante. O comprimento de uma String é o número de elementos nela.
As strings JavaScript são imutáveis. Isso significa que uma vez que uma string é criada, não é possível modificá-la.
No entanto, ainda é possível criar outra string com base em uma operação na string original. Por exemplo:
- Uma substring do original escolhendo letras individuais ou usando
substring(). - Uma concatenação de duas strings usando o operador de concatenação (
+) ouconcat().
Cuidado com a tipagem do seu código!
Pode ser tentador usar strings para representar dados complexos. Fazer isso traz benefícios a curto prazo:
- É fácil construir strings complexas com concatenação.
- Strings são fáceis de depurar (o que você vê impresso é sempre o que está na string).
- Strings são o denominador comum de muitas APIs (campos de entrada, valores de armazenamento local ,
XMLHttpRequestrespostas ao usarresponseText, etc.) e pode ser tentador trabalhar apenas com strings.
Com convenções, é possível representar qualquer estrutura de dados em uma string. Isso não faz com que seja uma boa ideia. Por exemplo, com um separador, pode-se emular uma lista (enquanto um array JavaScript seria mais adequado). Infelizmente, quando o separador é usado em um dos elementos da "lista", a lista é quebrada. Um caractere de escape pode ser escolhido, etc. Tudo isso requer convenções e cria uma carga de manutenção desnecessária.
Use strings para dados textuais. Ao representar dados complexos, parse strings e use a abstração apropriada.
Tipo Symbol
Um Symbol é um valor primitivo único e imutável e pode ser usado como a chave de uma propriedade Object (veja abaixo). Em algumas linguagens de programação, os símbolos são chamados de "átomos".
Para mais detalhes veja a página de referência Symbol.
Objetos
Na ciência da computação, um objeto é um valor na memória que possivelmente é referenciado por um identificador.
Propriedades
Em JavaScript, os objetos podem ser vistos como uma coleção de propriedades. Com a sintaxe literal de objeto, um conjunto limitado de propriedades é inicializado; então as propriedades podem ser adicionadas e removidas. Os valores de propriedade podem ser valores de qualquer tipo, incluindo outros objetos, o que permite construir estruturas de dados complexas. As propriedades são identificadas usando valores key. Um valor key é um String value ou um Symbol value.
Existem dois tipos de propriedades de objeto: A data property e a accessor property. Cada propriedade tem attributes correspondentes. Cada atributo é acessado internamente pelo mecanismo JavaScript, mas você pode defini-los por meio de Object.defineProperty() ou lê-los por meio de Object.getOwnPropertyDescriptor(). Você pode ler mais sobre as várias nuances na página Object.defineProperty().
Propriedade de dados
As propriedades de dados associam uma chave a um valor. Pode ser descrito pelos seguintes atributos:
value-
O valor recuperado por um acesso get da propriedade. Pode ser qualquer valor JavaScript.