~ 能简化判断是因为按位取反使 indexOf 返回的 -1 变为 0(falsy),其余非负索引变为非零数(truthy),从而用 if(~str.indexOf(c)) 直接判断存在性。

直接用 ~str.indexOf(char) 可以把“存在”转化为真值,“不存在”转化为假值,省去显式比较 !== -1。
为什么 ~ 能简化判断?
indexOf() 找不到时返回 -1,找到时返回非负整数(0, 1, 2...)。而按位取反运算符 ~ 的规则是:~n === -(n + 1)。所以:
-
~(-1) === 0→ 假值 -
~0 === -1→ 真值 -
~1 === -2→ 真值 -
~2 === -3→ 真值
也就是说,只有找不到(返回 -1)时,~(-1) 得到 0(falsy),其余全是非零数字(truthy)。于是 if (~str.indexOf('a')) 就等价于 “如果包含 'a'”。
常见误用与边界注意
这个技巧简洁,但要注意几点:
- 只适用于**只需判断存在性**的场景;若需索引位置,仍得用原返回值
-
~是位运算,操作数会先被转为 32 位有符号整数,但indexOf返回值始终在此范围内,安全 - 对空字符串
'':在非空字符串中查''总返回0(开头即匹配),~0 === -1→ 判定为“存在”,符合直觉 - 可链式使用,如
~s.indexOf('a') && ~s.indexOf('b')表示同时含 a 和 b
对比写法:更直观 vs 更简洁
传统写法:
if (str.indexOf('x') !== -1) { /* 存在 */ }位运算写法:
if (~str.indexOf('x')) { /* 存在 */ }后者字符更少、无重复标识符,适合条件密集的逻辑(如过滤、校验、模板渲染中的内联判断)。
现代替代建议(可选)
ES6+ 推荐优先使用语义更清晰的 includes():
if (str.includes('x')) { /* 存在 */ }它返回布尔值,无需位运算,可读性更好,且支持第二个参数(起始位置)。仅当需兼容极老环境(如 IE)时,才考虑 ~indexOf() 技巧。










