Como verificar se um elemento existe em um array JavaScript? De «apenas funciona» a «voa»
\n\nVocê já escreveu código e de repente congelou, olhando para um array de dados? «Será que tem aqui o que eu preciso?» — essa pergunta atormenta todo desenvolvedor. No Stack Overflow, o tópico How do I check if an array includes a value in JavaScript acumulou milhões de visualizações. E não é à toa. Uma tarefa aparentemente trivial, mas sua solução afeta não apenas a legibilidade do código, mas também a velocidade de toda a aplicação.
\n\nHoje vamos analisar todas as formas de verificar a presença de um elemento em um array JavaScript. Não vamos apenas mostrar os métodos — vamos conduzir uma verdadeira investigação de desempenho. Você descobrirá quando usar includes(), por que indexOf() às vezes é mais rápido e como Set pode acelerar seu código dezenas de vezes. Vamos lá!
Clássico do gênero: Array.prototype.includes()
\n\nA forma mais moderna e legível é o método includes(). Ele surgiu no ES2016 e rapidamente se tornou o padrão de facto. Por quê? Porque seu nome fala por si só.
\n\nconst fruits = ['apple', 'banana', 'mango', 'orange'];\nconst hasBanana = fruits.includes('banana');\nconsole.log(hasBanana); // true\n\nconst hasGrape = fruits.includes('grape');\nconsole.log(hasGrape); // false\n\n\nTudo simples e elegante. includes() usa comparação estrita (===), portanto, cuidado com os tipos de dados:
const numbers = [1, 2, 3];\nconsole.log(numbers.includes('1')); // false — string não é igual a número\n\n\nVantagens:
\n- \n
- Legibilidade 10/10 — o código é compreensível até para iniciantes \n
- Funciona com
NaN(ao contrário deindexOf) \n - Suportado por todos os navegadores modernos \n
Desvantagens:
\n- \n
- Complexidade linear O(n) — percorre todo o array \n
- Não é adequado se você precisar encontrar o índice do elemento \n
Veterano: Array.prototype.indexOf()
\n\nAntes do surgimento do includes(), todos usavam indexOf(). Este método retorna o índice do primeiro elemento encontrado ou -1 se o elemento estiver ausente.
const fruits = ['apple', 'banana', 'mango'];\nconst index = fruits.indexOf('banana');\nif (index !== -1) {\n console.log('Elemento encontrado na posição', index);\n} else {\n console.log('Elemento não encontrado');\n}\n\n\nMuitos se acostumaram com essa verificação, e ela ainda funciona. Mas há uma nuance importante: indexOf() não consegue encontrar NaN.
\n\nconst arr = [NaN];\nconsole.log(arr.indexOf(NaN)); // -1 — não encontra!\nconsole.log(arr.includes(NaN)); // true — encontra\n\n\nIsso ocorre porque NaN !== NaN em JavaScript, e indexOf usa comparação estrita. Já includes() usa o algoritmo SameValueZero, que lida corretamente com NaN.
Quando usar indexOf?
\n- \n
- Se você precisar do índice do elemento, e não apenas do fato de sua existência \n
- Se tiver certeza de que não há NaN no array \n
- Em código legado, onde não é possível usar ES2016+ \n
Lutador flexível: Array.prototype.find() e findIndex()
\n\nQuando você precisa verificar não apenas a existência, mas o cumprimento de uma condição, o find() vem em socorro. Ele aceita uma função de callback e retorna o primeiro elemento que satisfaz a condição, ou undefined.
const users = [\n { id: 1, name: 'Alice', age: 25 },\n { id: 2, name: 'Bob', age: 30 },\n { id: 3, name: 'Charlie', age: 35 }\n];\n\nconst user = users.find(u => u.age > 28);\nconsole.log(user); // { id: 2, name: 'Bob', age: 30 }\n\n// Verificação de existência\nconst exists = users.find(u => u.id === 4) !== undefined;\nconsole.log(exists); // fals