前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库findIndex 与 indexOf 查找场景区别
JavaScript数组与集合

找数组元素的下标,什么时候用 findIndex,什么时候用 indexOf?

能直接写出要找的那个值,用 indexOf,它按 === 逐个比较。要按条件找,比如「第一个年龄大于 30 的用户」,用 findIndex,它对每个元素调用你给的函数,第一个返回真值的下标就是结果。两者找不到都返回 -1。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数组与集合
先看核心答案读代码示例
理解线索

两种查找方式的本质区别

  1. indexOf(value)拿值去比,严格相等,不做类型转换,可以传起始位置
  2. findIndex(fn)拿条件去问,回调返回真值就停,条件可以任意复杂
  3. -1两者找不到时的共同返回值,判断时要写 !== -1

indexOf 会跳过空位,findIndex 会把空位当成 undefined 传给回调,所以在稀疏数组上找 undefined 两者结果不同。

核心回答

先记住这个答案

两者的差别在于怎么判断「找到了」。indexOf 接收一个值,用严格相等 === 和每个元素比,第一个相等的下标就是结果,适合找数字、字符串,或者你手上已经拿着的那个对象引用。findIndex 接收一个回调函数,对每个元素调用它,第一个返回真值的下标就是结果,所以能表达任意条件,比如按 id 找对象、按多个字段组合找。简单的判断方法是:能直接写出要比较的那个值,就用 indexOf;条件涉及属性或计算,就用 findIndex。

  • indexOf 按 === 比较,适合原始值和已有引用
  • findIndex 按回调条件找,适合对象和复杂条件
  • 对象字面量用 indexOf 永远找不到,引用不同
  • indexOf 找不到 NaN,用 findIndex 配合 Number.isNaN 可以

按值找和按条件找

最常见的场景是在对象数组里找某一项,这时两者的差别一眼就能看出来。

在对象数组里找JavaScript
const users = [{ id: 1, age: 25 }, { id: 2, age: 35 }]
const target = users[1] // 手上已有的引用

console.log(users.indexOf({ id: 2, age: 35 })) // 新对象,引用不同
console.log(users.indexOf(target)) // 同一个引用
console.log(users.findIndex((u) => u.age > 30)) // 按条件找
console.log([1, NaN].indexOf(NaN), [1, NaN].findIndex(Number.isNaN))
查看输出与解释
-1
1
1
-1 1

第一行返回 -1,因为 === 比较对象时比的是引用,也就是「是不是同一个对象」,不是「内容是否一样」。字面量 { id: 2, age: 35 } 是新建的对象,和数组里那个不是同一个。只有拿着同一个引用,比如 target,这时 indexOf 才能找到。 最后一行是 NaN 的情况。NaN === NaN 是 false,所以 indexOf 永远找不到它。findIndex 把判断交给你,传一个 Number.isNaN 就能找到。

严格相等带来的类型问题

indexOf 不做类型转换,数字和字符串是两回事。数据从 URL、表单、localStorage 里读出来时通常是字符串,拿数字去找就会失败。

字符串和数字,以及起始位置JavaScript
const ids = ['1', '2', '3'] // 从 URL 参数里拿到的是字符串
console.log(ids.indexOf(2)) // 严格相等,不做类型转换
console.log(ids.indexOf('2'))
console.log(ids.findIndex((id) => Number(id) === 2)) // 在回调里统一类型

console.log([1, 2, 1].indexOf(1, 1), [1, 2, 1].lastIndexOf(1)) // 从下标 1 开始找;从后往前找
查看输出与解释
-1
1
1
2 2

indexOf 的第二个参数 fromIndex 指定从哪里开始找,适合循环找出所有匹配位置。lastIndexOf 从后往前找。findIndex 没有起始位置参数,但 ES2023 加了 findLastIndex,可以从后往前按条件找。

性能上怎么选
两者都是从头线性查找,都是 O(n),找到就停。indexOf 不需要每次调用函数,开销略小,但普通业务数据量下差别可以忽略。如果同一个数组要按 id 反复查找,不如先建一个 Map,把每次查找降到 O(1)。
回答前,多想一步

容易答错的地方

用 indexOf 找对象
这是最常见的错误。users.indexOf({ id: 2 }) 永远是 -1,不管数组里有没有 id 为 2 的对象。按内容找对象只能用 findIndex 或 find。
用返回值直接做条件判断
if (arr.indexOf(x)) 在元素位于下标 0 时判断为假,不存在时返回 -1 反而判断为真,逻辑正好反了。要写 arr.indexOf(x) !== -1,只关心有没有的话直接用 includes。
以为两者在稀疏数组上表现一样
[, 1].indexOf(undefined) 返回 -1,因为 indexOf 会跳过空位;[, 1].findIndex((x) => x === undefined) 返回 0,因为 findIndex 会访问每个下标,空位读出来就是 undefined。
试着用自己的话回答

面试官还会怎么问?

find 和 findIndex 什么时候用哪个?

需要元素本身用 find,需要位置用 findIndex,比如要 splice 删除或者替换某一项时。find 找不到返回 undefined,如果数组里本来就可能存 undefined,就分不清是没找到还是找到了 undefined,这时用 findIndex 更可靠。

要找出所有满足条件的下标怎么写?

没有内置方法。可以用 reduce 收集,或者写成 arr.map((x, i) => (cond(x) ? i : -1)).filter((i) => i !== -1)。按值找所有位置时,可以用 indexOf 配合 fromIndex 循环查找。

回调里能拿到哪些参数?

findIndex 的回调接收三个参数:当前元素、当前下标、数组本身。findIndex 自己还有第二个参数 thisArg,用来指定回调里的 this,不过用箭头函数时这个参数不起作用。

从一道题,走向一组知识

把知识连起来

数组与集合

数组的 includes 和 indexOf 能找到 NaN 吗?两者还有哪些差别?

indexOf 找不到 NaN,而 includes 能找到,差别在于两者用的相等算法不同。

数组与集合

什么是类数组对象?arguments 和真数组有什么区别,怎么转换?

arguments 这类类数组没有 indexOf 和 findIndex,要先转成数组或者用 call 借用。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • Array.prototype.findIndex()
  • Array.prototype.indexOf()

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 按值找和按条件找
  3. 严格相等带来的类型问题
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑