判断一段文字里有没有某个词,比如校验用户名里是否含空格、地址里是否带某个参数名,js 字符串包含的判断有四五种写法,场景不同选法不同。

最直接的是 ES6 的 includes 方法,返回 true 或 false:

let str = 'hello world';  str.includes('world');  // true  str.includes('World');  // false,区分大小写  str.includes('o', 5);  // 从下标 5 开始找,返回 true

老项目要兼容 IE 的话,includes 用不了,用 indexOf 判断:

if (str.indexOf('world') !== -1) { console.log('包含了'); }

indexOf 返回第一次出现的位置,找不到返回 -1,拿它和 -1 比较就是包含判断。它的兼容性覆盖所有老浏览器,这也是很多老代码里满屏 indexOf 的原因。ES5 环境和部分老安卓 WebView 不认 includes,移动端做兼容方案时留意。

要按规则匹配,用正则

固定文字用上面两个就够,遇到以 abc 开头、包含某前缀这类规则匹配,正则更合适:

/abc/.test(str);   // 是否包含 abc   /^abc/.test(str);   // 是否以 abc 开头

test 想匹配变量,得用 new RegExp(变量) 来构造正则。search 方法也能接正则,返回位置、找不到返回 -1,用法和 indexOf 类似,只是参数换成正则。

容易忽略的细节

  • includes 和 indexOf 都区分大小写,想忽略大小写先把两边统一转成小写再比。
  • indexOf 匹配空字符串会返回 0,也就是「包含」,用它校验非空会出 bug。
  • includes 的第二个参数是起始下标,传负数会按下标加长度来算。

选择建议:js 字符串包含判断,固定字符用 includes,兼容老浏览器用 indexOf,带规则的匹配交给正则 test,按这三条选基本不会错。