includes语义更清晰、可读性更好,indexOf在匹配失败时略快但差异极小;includes基于indexOf实现,多一次比较操作,实际性能差距可忽略;应优先根据语义选型而非微小性能差异。

在日常开发中,indexOf 和 includes 都常用于判断字符串是否包含某子串,但它们的底层实现和性能表现并不完全相同。简单说:includes 语义更清晰、可读性更好,而 indexOf 在某些场景下略快,尤其在匹配失败时;但实际差异极小,通常不应成为选型的主要依据。
底层机制决定性能倾向
indexOf 返回首次匹配位置(数字)或 -1,内部使用优化过的字符遍历算法,部分引擎(如 V8)对 ASCII 纯英文短串做了特殊加速;includes 本质是基于 indexOf 实现的(ES2016 规范明确要求 includes(value) 等价于 indexOf(value) !== -1),因此它多了一次数值比较操作,理论上存在微小开销。
- 匹配成功时,两者耗时几乎一致,差异在纳秒级
- 匹配失败时,indexOf 直接返回 -1,includes 还需做一次 !== -1 判断——但现代 JS 引擎会内联优化,实际差距可忽略
- 当搜索内容含 Unicode 字符(如 emoji 或中文)时,两者都需按 UTF-16 编码单位处理,性能表现也基本持平
实际项目中更应关注可读性与语义
includes 的布尔返回值直白表达“是否含有”,符合人类阅读习惯;indexOf 的 -1 判断容易出错(比如误写成 if (str.indexOf('x')) 导致 'x' 在开头时被误判为 false)。
- 需要获取位置信息(如截取、替换、高亮)——必须用 indexOf(或更现代的 findIndex 配合 Array.from)
- 仅做存在性校验(如权限判断、关键词过滤)——优先用 includes,代码更安全、意图更明确
- 若在高频循环中执行数万次查找,且已确认是性能瓶颈,可用 indexOf + 缓存策略,但这种情况极少
简单测试结果参考(Chrome 125,Node.js 20)
对 10 万字符长字符串查找不存在的子串 10 万次:
立即学习“Java免费学习笔记(深入)”;
- indexOf 平均耗时约 18–22ms
- includes 平均耗时约 19–24ms
- 差异不到 5%,且受字符串内容、V8 版本、CPU 缓存影响波动明显
换成真实业务场景(如校验用户输入是否含敏感词),这种差异远小于一次 DOM 操作或正则匹配的开销。
替代方案:何时该考虑其他方法
如果真遇到字符串查找性能问题,往往不是 indexOf vs includes 的选择问题,而是设计层面可优化:
- 大量重复查找同一字符串?考虑提前用 Set 或 Map 建立索引
- 需模糊匹配或前缀/后缀判断?用 startsWith / endsWith,它们比 indexOf 更精准且同样高效
- 涉及复杂模式(如通配符、多关键词)?应转向正则或专用库(如 fuse.js),而非纠结基础 API
不复杂但容易忽略:多数性能问题出在算法逻辑或数据结构上,而不是这两个字符串方法本身。











