Como Obter o Último Valor Correspondente de um Array em JavaScript
Você precisa encontrar o último elemento em um array que corresponda a uma condição. Talvez seja o log de erro mais recente, a última entrada de formulário válida ou o último usuário que estava ativo. Antes do ES2023, isso significava soluções alternativas desajeitadas—reverter arrays, filtrar tudo ou escrever loops manuais. Agora existe uma maneira mais limpa.
Pontos-Chave
- Use
findLast()para recuperar o último elemento do array que corresponda a uma condição sem mutar o array original. - Use
findLastIndex()quando você precisar da posição em vez do valor em si. - Evite usar
reverse().find()pois isso muta o array original e introduz bugs sutis. - Lembre-se dos diferentes valores de retorno:
findLast()retornaundefinedquando nenhuma correspondência é encontrada, enquantofindLastIndex()retorna-1.
A Solução Moderna: Array.prototype.findLast()
Array.prototype.findLast() itera de trás para frente através de um array e retorna o primeiro elemento que satisfaz seu predicado. É o espelho de find(), que busca desde o início.
const logs = [
{ type: 'info', message: 'Started' },
{ type: 'error', message: 'Connection failed' },
{ type: 'info', message: 'Retrying' },
{ type: 'error', message: 'Timeout' }
]
const lastError = logs.findLast(log => log.type === 'error')
// { type: 'error', message: 'Timeout' }
Se nenhum elemento corresponder, findLast() retorna undefined. Isso torna seguro usar com optional chaining:
const lastError = logs.findLast(log => log.type === 'critical')?.message ?? 'No critical errors'
findLast vs findLastIndex: Quando Você Precisa da Posição
Às vezes você precisa do índice, não do valor. É isso que findLastIndex() fornece. Ele retorna o índice do último elemento correspondente, ou -1 se nada corresponder.
const numbers = [1, 5, 3, 8, 2, 9, 4]
const lastLargeIndex = numbers.findLastIndex(n => n > 7)
// 5 (o índice de 9)
Use findLastIndex() quando você precisar fazer splice, slice a partir dessa posição ou referenciar elementos vizinhos.
Compatibilidade de Navegadores e Fallbacks
Tanto findLast() quanto findLastIndex() fazem parte do ES2023 e têm amplo suporte em navegadores modernos e versões recentes do Node.js. No entanto, ambientes mais antigos podem não incluí-los.
Se o TypeScript reclamar sobre esses métodos, seu tsconfig.json provavelmente precisa de "lib": ["ES2023"] ou mais recente nas opções do compilador.
Para ambientes sem suporte nativo, aqui está um fallback limpo que não muta o array original:
function findLast(arr, predicate) {
for (let i = arr.length - 1; i >= 0; i--) {
if (predicate(arr[i], i, arr)) {
return arr[i]
}
}
return undefined
}
Este loop reverso é eficiente—ele para na primeira correspondência e evita criar arrays intermediários.
Discover how at OpenReplay.com.
Armadilhas Comuns a Evitar
Não reverta o array para usar find():
// ❌ Muta o array original!
const last = arr.reverse().find(x => x > 5)
// ✅ Use findLast em vez disso
const last = arr.findLast(x => x > 5)
Chamar reverse() modifica seu array no local. Isso cria bugs sutis que são dolorosos de depurar.
Não confunda os valores de retorno:
findLast()retorna o elemento ouundefinedfindLastIndex()retorna o índice ou-1
Verificar truthiness funciona para findLast(), mas com findLastIndex() você deve verificar explicitamente por -1:
const index = arr.findLastIndex(x => x > 100)
if (index !== -1) {
// Encontrou
}
Cuidado com correspondências falsy:
Se seu array contém 0, false ou strings vazias, certifique-se de que seu predicado os manipule corretamente:
const values = [1, 2, 0, false, 'last']
values.findLast(x => x) // 'last' (pula valores falsy)
values.findLast(() => true) // 'last' (obtém o último elemento real)
Quando Escolher Cada Abordagem
| Necessidade | Método |
|---|---|
| Último elemento correspondente a uma condição | findLast() |
| Índice do último elemento correspondente | findLastIndex() |
| Último elemento simples (sem condição) | arr.at(-1) ou arr[arr.length - 1] |
| Busca de valor exato | lastIndexOf() |
Conclusão
Para obter o último valor correspondente de um array em JavaScript, recorra primeiro a findLast(). É legível, não muta seus dados e para assim que encontra uma correspondência. Quando você precisar da posição em vez do valor, use findLastIndex(). Para ambientes mais antigos, um loop reverso simples fornece um fallback confiável sem os riscos de mutação de reverse(). Mantenha seus predicados explícitos e lembre-se dos diferentes valores de retorno—undefined versus -1—para evitar falhas silenciosas.
Perguntas Frequentes
Sim, findLast() funciona em arrays esparsos. Ele itera de trás para frente através do array e pula slots vazios, invocando o predicado apenas para elementos que realmente existem. Este comportamento espelha como find() manipula arrays esparsos ao iterar para frente.
findLast() é mais eficiente porque para de iterar assim que encontra uma correspondência. Usar filter().pop() processa o array inteiro primeiro, criando um novo array na memória, e então recupera o último elemento. Para arrays grandes, findLast() oferece ganhos significativos de desempenho.
Sim, findLast() suporta generics do TypeScript e type narrowing. Quando você usa um type guard como seu predicado, o TypeScript infere corretamente o tipo narrowed para o elemento retornado. Certifique-se de que seu tsconfig.json inclui ES2023 no array lib para definições de tipo adequadas.
Sim, você pode adicionar um polyfill ao Array.prototype se o método não existir. Verifique a existência do método primeiro, então atribua uma função que faça loop de trás para frente através do array. Core-js e outras bibliotecas de polyfill também fornecem implementações prontas para compatibilidade mais ampla.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.