判断字符串是否包含某字符应据需求选方法:问“有没有”用includes()(返回布尔值,语义清晰、兼容nan/undefined),问“在哪儿”用indexof()(返回索引,兼容旧浏览器但特殊值识别不准)。

判断字符串是否包含某个字符,最常用的是 includes() 和 indexOf()。选哪个不看“哪个更快”,而要看“你想知道什么”:是想知道“有没有”,还是想知道“在哪儿”。
用途决定方法:问“有没有”用 includes,问“在哪儿”用 indexOf
includes() 只回答一个布尔问题:子串是否存在?返回 true 或 false,语义直接,适合条件判断。
-
"hello".includes("e")→true -
if (str.includes("admin")) { ... }—— 安全、易读、不易出错
indexOf() 回答的是位置问题:它从左到右扫描,返回子串首次出现的索引(≥0),没找到就返回 -1。
-
"hello".indexOf("e")→1 -
"hello".indexOf("z")→-1 - 若要用于判断,必须写成
str.indexOf("x") !== -1;写成if (str.indexOf("x"))会把开头匹配(索引为 0)误判为 false
兼容性与特殊值处理差异
indexOf() 兼容老浏览器(IE9+),但对某些特殊值识别不准:
-
[1, 2, NaN].indexOf(NaN)→-1(错误,NaN 不等于自身) -
[undefined, "a"].indexOf(undefined)→-1
includes() 使用严格相等(=== 的扩展规则),能正确识别这些值:
-
[1, 2, NaN].includes(NaN)→true -
[undefined, "a"].includes(undefined)→true
如果你的数组可能含 NaN 或 undefined,且需准确判断存在性,includes() 更可靠。
大小写与类型转换要注意
两者都区分大小写,且不会自动做类型转换:
-
"123".includes(2)→true(字符串中查找数字,会隐式转为字符串) -
[1, 2, 3].includes("2")→false(数组严格比较,"2" ≠ 2) -
"Hello".includes("h")→false(小写 h 不匹配大写 H)
如需忽略大小写,不能靠这两个方法直接实现,应改用 search() 或正则 test():
/hello/i.test(str)-
str.toLowerCase().includes("hello")(简单场景可用,注意性能开销)
性能差异其实可以忽略
现代引擎(V8、SpiderMonkey)中,includes() 多数是基于 indexOf() 实现的,仅多一次 !== -1 判断,耗时差距在纳秒级。
- 10 万次查找测试中,
includes平均比indexOf !== -1慢约 0.07ms - 真正影响性能的是重复查找、未缓存结果、或在长文本中高频调用
- 除非已确认是性能瓶颈,否则不必为这点差异牺牲可读性











