Arrays em JavaScript: criar, ler e entender por dentro
Array em JavaScript é um objeto com chaves numéricas — por isso typeof devolve object, existem buracos e índice fora do range volta undefined, não erro.
Array é uma estrutura de dados que mantém valores em uma sequência. Você cria a
lista com colchetes, acessa cada item por um índice que começa em zero e consulta
a quantidade de posições com .length.
Imagine um armário com compartimentos numerados. O array é o armário, cada
índice é o número de uma porta e o valor é o que está guardado ali. Abrir a
porta 0 entrega o primeiro item; pedir uma porta que não existe não derruba o
armário, apenas devolve undefined. No JavaScript, porém, esses números são
chaves de um objeto com comportamento especial — e não compartimentos físicos.
Esse detalhe explica por que typeof devolve 'object', por que existe
Array.isArray, como surgem posições vazias e por que o undefined de um
índice inválido costuma causar erro apenas algumas linhas depois.
Todos os exemplos são da mesma loja virtual que aparece em variáveis em JavaScript: carrinho, produto, pedido.
Criar um array e ler pelo índice
const carrinho = ['Teclado mecânico', 'Mouse sem fio', 'Headset'];
console.log(carrinho[0]);
console.log(carrinho[2]);
console.log(carrinho.length);
console.log(carrinho);Três itens, índices 0, 1 e 2. O último índice é sempre length - 1 — o erro de
somar um a mais aqui tem nome próprio em inglês, off-by-one, e é responsável
por boa parte dos undefined que você vai caçar na vida.
Por que typeof diz “object”
const precos = [289.9, 149.9, 399];
console.log(typeof precos);
console.log(typeof precos[0]);
console.log(Array.isArray(precos));
console.log(Object.keys(precos));
console.log(precos['1']);Olhe a penúltima linha: as chaves do array são as strings '0', '1' e
'2'. E a última prova o outro lado: precos['1'] funciona igual a
precos[1], porque o motor converte o índice para string antes de procurar.
Array não é um tipo primitivo do JavaScript. É um objeto com um comportamento
especial ligado às chaves numéricas e ao length. Por isso typeof nunca vai
te ajudar a distinguir um array de um objeto comum — e por isso existe
Array.isArray, que é a checagem correta.
Dá para pendurar propriedade num array
Como array é objeto, nada impede você de gravar uma chave não numérica nele. O
motor aceita em silêncio, e o length finge que não viu:
const itens = ['Teclado mecânico', 'Mouse sem fio'];
itens.origem = 'importado';
console.log(itens.length);
console.log(itens);
console.log(Object.keys(itens));length continua 2, mas Object.keys mostra três chaves. O Node até avisa
imprimindo origem: 'importado' fora da contagem. Isso não é um recurso para
usar: é uma explicação. Quando você precisar de nome e lista junto, use um
objeto com um array dentro ({ origem: 'importado', itens: [...] }), não um
array com propriedade grudada.
length é gravável, e isso corta ou estica o array
Na maioria das linguagens o tamanho da lista é leitura. Aqui, não:
const carrinho = ['Teclado mecânico', 'Mouse sem fio', 'Headset', 'Webcam'];
carrinho.length = 2;
console.log(carrinho);
carrinho.length = 4;
console.log(carrinho);
console.log(carrinho[3]);
carrinho.length = 0;
console.log(carrinho, carrinho.length);Diminuir length descarta os itens do fim, e não tem volta: aumentar de
novo não traz 'Headset' de lugar nenhum, traz dois buracos. E length = 0
esvazia o array inteiro numa linha.
Esse truque do length = 0 aparece em código real porque ele esvazia o array
no lugar, sem trocar a referência — quem mais aponta para aquele array vê o
array vazio também. Se você fizer carrinho = [], cria um array novo e deixa o
antigo intacto para os outros. São efeitos diferentes; escolha o que você quer.
Buraco não é undefined: o array esparso
Escrever num índice muito além do fim não dá erro. Cria vazio:
const estoque = [];
estoque[0] = 12;
estoque[4] = 3;
console.log(estoque);
console.log(estoque.length);
console.log(estoque[2]);
console.log(1 in estoque);
console.log(estoque.map((n) => n * 2));Quatro coisas acontecem de uma vez. O length virou 5 sozinho. O Node imprime
<3 empty items> em vez de undefined, undefined, undefined, porque essas
posições não existem como chave. 1 in estoque é false — é assim que se
distingue um buraco de uma posição que existe e vale undefined. E o map
pulou os buracos: ele nem chamou a função para eles.
Índice fora do range devolve undefined, não erro
const carrinho = ['Teclado mecânico', 'Mouse sem fio', 'Headset'];
console.log(carrinho[3]);
console.log(carrinho[10]);
console.log(carrinho[-1]);
console.log(carrinho.at(-1));Nenhuma das três primeiras linhas quebrou. O motor procurou uma propriedade
chamada '3', '10' e '-1', não achou e devolveu undefined — o mesmo que
faria com carrinho.qualquerCoisa. Linguagens como Python levantam IndexError
aqui; JavaScript, não.
Isso é a diferença entre falhar na hora e falhar depois. O programa segue
carregando um undefined até o momento em que alguém tenta ler algo dentro
dele. Aí, sim, ele para.
at(-1) é a exceção que confirma a regra: é um método, não uma leitura de
chave, e conta a partir do fim.
O erro: Cannot read properties of undefined
Este é o erro número um de quem está aprendendo array. Um catálogo de três produtos e uma leitura na posição 10:
const produtos = [
{ nome: 'Teclado mecânico', preco: 289.9 },
{ nome: 'Mouse sem fio', preco: 149.9 },
{ nome: 'Headset', preco: 399 },
];
console.log(produtos[10].nome);Leia a mensagem de trás para a frente. reading 'nome' é o que você tentou ler;
of undefined é o que estava no lugar do objeto. Ou seja: produtos[10] é
que é undefined, não nome. O array não reclamou do índice 10 — ele
entregou undefined e a linha seguinte tropeçou.
O caret aponta para a coluna 26, o n de nome — a primeira letra logo depois
do ponto. Sempre que a seta cair depois de um ., o culpado é o que está à
esquerda dele, nunca o nome que ela está apontando. Se esse erro
é o seu companheiro diário, o
guia do TypeError: Cannot read properties of undefined
cobre os outros cenários em que ele aparece.
Três formas de não cair nele:
const produtos = [
{ nome: 'Teclado mecânico', preco: 289.9 },
{ nome: 'Mouse sem fio', preco: 149.9 },
{ nome: 'Headset', preco: 399 },
];
console.log(produtos[10]?.nome);
console.log(produtos.at(-1).nome);
const webcam = produtos.find((p) => p.nome === 'Webcam');
console.log(webcam?.preco ?? 'produto fora do catálogo');O ?. (encadeamento opcional) devolve undefined em vez de quebrar. O ??
(coalescência nula) entrega um valor de reserva. E at(-1) resolve a
necessidade mais comum — “o último” — sem você calcular índice nenhum.
Array de objetos: o formato de um carrinho de verdade
Na prática, array de string quase não aparece. O que aparece é array de objeto, porque cada linha do carrinho tem mais de uma informação:
const carrinho = [
{ nome: 'Teclado mecânico', preco: 289.9, quantidade: 1 },
{ nome: 'Mouse sem fio', preco: 149.9, quantidade: 2 },
];
const total = carrinho.reduce((soma, item) => soma + item.preco * item.quantidade, 0);
console.log(carrinho.length, 'itens');
console.log('R$', total.toFixed(2));Repare que carrinho.length diz 2 linhas, não 3 peças. Quantidade é campo
do item; tamanho é do array. Trocar um pelo outro é o motivo mais comum de o
badge do carrinho mostrar um número e o checkout cobrar outro.
Cópia e referência
Array é um valor de referência: a variável guarda um endereço, não o conteúdo.
const original = ['Teclado mecânico', 'Mouse sem fio'];
const apelido = original;
const copia = [...original];
apelido.push('Headset');
console.log(original);
console.log(copia);
console.log(original === apelido, original === copia);apelido e original são dois nomes para o mesmo array — mexeu em um,
mexeu no outro. copia é um array novo com os mesmos valores dentro. E
=== entre arrays compara o endereço, nunca o conteúdo: dois arrays com itens
idênticos são sempre diferentes para o ===.
O que levar desta lição
Quatro frases que resolvem a maior parte dos bugs de array de iniciante:
- O último índice é
length - 1. Se você escreveu<=no laço, tem umundefinedesperando. - Índice inválido não dá erro; dá
undefined. O erro vem uma linha depois, quando alguém lê dentro desseundefined. lengthé escrita, não só leitura — elength = 0esvazia sem trocar a referência.- Só
Array.isArrayresponde “isto é um array?”.typeofresponde'object'para array, objeto,nulle data.
Teste o modelo do armário: crie const letras = ['A', 'B', 'C'], imprima
letras[2], letras[3] e letras.at(-1), depois atribua letras[5] = 'F'.
Confirme que o tamanho virou 6 e investigue as posições 3 e 4. Se você
consegue explicar por que há buracos sem confundi-los com valores escritos como
undefined, entendeu a parte mais importante da estrutura.
A próxima lição da trilha de JavaScript é
adicionar e remover elementos de um array,
onde push, splice e companhia mostram que const nunca prometeu proteger o
conteúdo. Depois vem
percorrer array em JavaScript. O
guia completo de JavaScript mostra a ordem inteira.
Perguntas frequentes
Por que typeof de um array devolve "object"?
Array em JavaScript tem tamanho fixo?
Posso guardar tipos diferentes no mesmo array?
Qual a diferença entre lista[-1] e lista.at(-1)?
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
Todo o código deste artigo foi executado em Node 24.16.0, e as saídas exibidas são as reais — como produzimos este conteúdo.
Fontes consultadas
- MDN — Indexed collections — developer.mozilla.org
- MDN — Array — developer.mozilla.org
- ECMAScript 2026 Language Specification — Array Exotic Objects — tc39.es


