Buscar elemento em array: find, includes e indexOf
find devolve o elemento, findIndex o índice e filter um array. Veja também por que indexOf não acha objeto igual nem NaN, com saída real no Node.
Buscar em um array começa pela pergunta que você quer responder: “qual é o produto?”, “em que posição ele está?”, “existe algum?” ou “quais atendem à condição?”. O JavaScript oferece métodos diferentes porque cada pergunta pede um tipo de resposta diferente.
Imagine pedir ajuda numa biblioteca. find entrega o primeiro livro que atende
ao pedido; findIndex informa a posição dele na estante; some responde apenas
sim ou não; filter monta uma pilha com todos os resultados. No array, o
bibliotecário é a função de teste executada para cada item. O método pode parar
no primeiro acerto ou percorrer a lista inteira, conforme a resposta prometida.
Em termos técnicos, find devolve o elemento, findIndex devolve o índice,
filter devolve um novo array, includes devolve um booleano e indexOf
devolve a posição de um valor simples. Quando nada aparece, um método de
elemento devolve undefined; um método de posição devolve -1.
Os exemplos usam o catálogo de uma loja de periféricos, o mesmo domínio de variáveis em JavaScript.
find devolve o elemento, não o índice
find recebe uma função que responde sim ou não para cada item e devolve o
primeiro item que responde sim.
const produtos = [
{ sku: 'TEC-001', nome: 'Teclado mecânico', preco: 289.9, estoque: 12 },
{ sku: 'MOU-014', nome: 'Mouse sem fio', preco: 149.9, estoque: 0 },
{ sku: 'CAD-220', nome: 'Cadeira gamer', preco: 1199, estoque: 3 },
];
const achado = produtos.find((p) => p.sku === 'CAD-220');
console.log(achado);
console.log(achado.nome, achado.preco);O objeto que saiu do find é o mesmo objeto que está no array, não uma
cópia. Alterar achado.estoque altera o array. Isso é conveniente quando você
quer editar o item e incômodo quando você achava que estava trabalhando com uma
cópia.
Trocando o método, a mesma condição responde outra coisa:
const produtos = [
{ sku: 'TEC-001', nome: 'Teclado mecânico', categoria: 'periferico' },
{ sku: 'MOU-014', nome: 'Mouse sem fio', categoria: 'periferico' },
{ sku: 'CAD-220', nome: 'Cadeira gamer', categoria: 'movel' },
];
const ehPeriferico = (p) => p.categoria === 'periferico';
console.log(produtos.find(ehPeriferico));
console.log(produtos.findIndex(ehPeriferico));
console.log(produtos.filter(ehPeriferico));Mesma função de teste, três respostas: um objeto, um número e um array. A função que você passa é um callback comum, do tipo que a lição de funções em JavaScript mostra em detalhe.
Quando nada é encontrado
Aqui está a diferença que decide como você escreve a próxima linha:
const produtos = [
{ sku: 'TEC-001', nome: 'Teclado mecânico' },
{ sku: 'MOU-014', nome: 'Mouse sem fio' },
];
console.log(produtos.find((p) => p.sku === 'MON-007'));
console.log(produtos.findIndex((p) => p.sku === 'MON-007'));
console.log(produtos.filter((p) => p.sku === 'MON-007'));Três formas diferentes de dizer “não achei”. A do find é a perigosa: um
undefined que segue viajando pelo programa até alguém tentar ler uma
propriedade dele. O -1 do findIndex também engana, porque é um número
válido e if (indice) considera -1 verdadeiro. Sempre compare com
!== -1, nunca teste a verdade do índice.
includes e indexOf são para valores simples
Quando o array guarda strings ou números, você não precisa de callback nenhum:
const cuponsAtivos = ['PRIMEIRACOMPRA', 'FRETEGRATIS', 'BLACKFRIDAY'];
console.log(cuponsAtivos.includes('FRETEGRATIS'));
console.log(cuponsAtivos.indexOf('FRETEGRATIS'));
console.log(cuponsAtivos.indexOf('NATAL10'));
console.log(cuponsAtivos.includes('fretegratis'));A última linha é o bug mais comum com cupom: a comparação é sensível a
maiúsculas. Normalize com .trim().toUpperCase() antes de comparar o que veio
do formulário.
Os dois aceitam uma posição inicial como segundo argumento, e existe ainda o
lastIndexOf, que procura do fim para o começo:
const skusDoCarrinho = ['TEC-001', 'MOU-014', 'TEC-001'];
console.log(skusDoCarrinho.indexOf('TEC-001'));
console.log(skusDoCarrinho.lastIndexOf('TEC-001'));
console.log(skusDoCarrinho.indexOf('TEC-001', 1));
console.log(skusDoCarrinho.includes('TEC-001', 2));Objeto igual não é o mesmo objeto
Esta é a armadilha que mais consome tempo de quem está começando. includes e
indexOf comparam com igualdade estrita — e dois objetos com exatamente o
mesmo conteúdo não são iguais em JavaScript.
const carrinho = [{ sku: 'TEC-001', quantidade: 1 }];
console.log(carrinho.includes({ sku: 'TEC-001', quantidade: 1 }));
console.log(carrinho.indexOf({ sku: 'TEC-001', quantidade: 1 }));
const mesmoItem = carrinho[0];
console.log(carrinho.includes(mesmoItem));
console.log(carrinho.some((item) => item.sku === 'TEC-001'));As duas primeiras linhas falharam porque o objeto escrito dentro do includes
é um objeto novo, criado naquele instante, que por acaso tem o mesmo conteúdo.
A terceira funcionou porque mesmoItem é literalmente a mesma referência
guardada no array.
O caso NaN
Existe exatamente um valor em que includes e indexOf discordam, e ele
aparece sempre que uma conversão de número dá errado — nota de avaliação vinda
de um campo de texto, preço lido de uma planilha:
const notas = [4.5, 5, Number('quatro'), 3];
console.log(notas);
console.log(notas.indexOf(NaN));
console.log(notas.includes(NaN));
console.log(notas.findIndex(Number.isNaN));indexOf usa ===, e NaN === NaN é false — regra do padrão de ponto
flutuante, não capricho da linguagem. includes usa outro algoritmo de
comparação, o SameValueZero, em que NaN é igual a si mesmo. Se você precisa
da posição, findIndex(Number.isNaN) resolve.
some e every: existe algum? valem todos?
Quando a pergunta é sim ou não sobre a coleção inteira, esses dois dizem a intenção melhor do que qualquer laço:
const itens = [
{ sku: 'TEC-001', estoque: 12 },
{ sku: 'MOU-014', estoque: 0 },
{ sku: 'CAD-220', estoque: 3 },
];
console.log(itens.some((i) => i.estoque === 0));
console.log(itens.every((i) => i.estoque > 0));
const carrinhoVazio = [];
console.log(carrinhoVazio.every((i) => i.estoque > 0));
console.log(carrinhoVazio.some((i) => i.estoque > 0));Repare na terceira linha. every de um array vazio é true. Não é bug: a
afirmação “todos os itens têm estoque” é verdadeira quando não existe item
nenhum que a contrarie — é o chamado verdadeiro vacuoso. Na prática isso vira
um pedido vazio passando pela validação de estoque e seguindo para o pagamento.
Se o carrinho vazio não pode passar, teste o tamanho antes:
itens.length > 0 && itens.every(...).
Buscar do fim para o começo
findLast e findLastIndex fazem o mesmo trabalho do find, varrendo na
ordem inversa. É o que você quer quando a lista está em ordem cronológica e
interessa o evento mais recente:
const pedidos = [
{ id: 1041, cliente: 'Ana', status: 'pago' },
{ id: 1042, cliente: 'Bruno', status: 'cancelado' },
{ id: 1043, cliente: 'Ana', status: 'pago' },
{ id: 1044, cliente: 'Carla', status: 'aguardando' },
];
console.log(pedidos.find((p) => p.status === 'pago'));
console.log(pedidos.findLast((p) => p.status === 'pago'));
console.log(pedidos.findLastIndex((p) => p.status === 'pago'));A alternativa antiga era inverter o array antes de procurar — o que copiava a lista inteira só para achar um item. Se a ordem em que os itens estão te importa, vale ler a lição de ordenar array com sort antes de confiar na sequência que veio da API.
Erros comuns: o find que não achou
Este é o erro número um de quem aprendeu find hoje. O código funciona com o
SKU certo e explode com o SKU digitado errado:
const produtos = [
{ sku: 'TEC-001', nome: 'Teclado mecânico', preco: 289.9 },
{ sku: 'MOU-014', nome: 'Mouse sem fio', preco: 149.9 },
];
const codigoDigitado = 'MOU-15';
const produto = produtos.find((p) => p.sku === codigoDigitado);
console.log(`Produto: ${produto.nome}`);O erro não está na linha 9: está na linha 7, onde o find devolveu undefined
e ninguém conferiu. A mensagem Cannot read properties of undefined sempre
aponta para o uso, nunca para a origem — o diagnóstico completo está em
TypeError: Cannot read properties of undefined.
A correção tem duas metades: uma guarda explícita quando o programa precisa
reagir à ausência, e ?. com ?? quando um valor de reserva basta.
const produtos = [
{ sku: 'TEC-001', nome: 'Teclado mecânico', preco: 289.9 },
{ sku: 'MOU-014', nome: 'Mouse sem fio', preco: 149.9 },
];
function descrever(codigo) {
const produto = produtos.find((p) => p.sku === codigo);
if (!produto) return `SKU ${codigo} não está no catálogo`;
return `${produto.nome} — R$ ${produto.preco.toFixed(2)}`;
}
console.log(descrever('TEC-001'));
console.log(descrever('MOU-15'));
const talvez = produtos.find((p) => p.sku === 'MOU-15');
console.log(talvez?.nome ?? 'sem nome');Qual usar em cada caso
| pergunta | método | devolve quando acha | devolve quando não acha |
|---|---|---|---|
| qual é o item? | find |
o elemento | undefined |
| em que posição está? | findIndex |
o índice | -1 |
| quais são todos? | filter |
array com os itens | [] |
| existe algum? | some |
true |
false |
| valem todos? | every |
true |
false (e true se vazio) |
| esse valor simples está aí? | includes |
true |
false |
| em que posição está esse valor? | indexOf |
o índice | -1 |
Três hábitos que evitam a maior parte dos problemas: escolha pelo que você vai
fazer com a resposta, não pelo método que lembrou primeiro; nunca encadeie um
acesso a propriedade logo depois de um find; e para array de objetos prefira
some a includes, sempre.
Agora transforme uma pergunta em código: com os produtos do artigo, descubra
se existe algum item sem estoque, recupere o primeiro produto acima de R$ 500 e
liste todos abaixo de R$ 300. Os tipos esperados são boolean, objeto ou
undefined, e array. Imprima também um SKU inexistente para confirmar que sua
guarda trata a ausência antes de acessar .nome.
A próxima lição da trilha de JavaScript trata de ordenar array com sort, e logo depois vêm as receitas completas de array de objetos — somar, agrupar e detectar duplicado. O guia completo de JavaScript mostra onde cada assunto entra na sequência.
Perguntas frequentes
Uso find ou filter quando sei que só existe um resultado?
Posso usar includes para procurar um objeto dentro de um array?
Por que indexOf não encontra NaN e includes encontra?
some e every percorrem o array inteiro?
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 — Array.prototype.find() — developer.mozilla.org
- MDN — Array.prototype.includes() — developer.mozilla.org
- ECMAScript 2026 Language Specification — SameValueZero — tc39.es


