「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。
经常能看到代码里写着if(~arr.indexOf(x)){},但是你知道别人为什么可以这么写吗?其中的原理又是什么呢?
1.位运算符
字位运算符只适用 于32位整数,运算符会强制操作数使用32位格式,这是通过抽象操作ToInt32来实现的(ES5规范9.5节)。ToInt32首先执行ToNumber强制类型转换,比如"123"会先被转换成123,再去执行ToInt32操作。
2.非运算符
其中字位运算符有&、|、^、~ 、<<、>>、>>>,我们今天只讨论 ~ 运算符。非运算符是将操作数的所有位都反转,我们来看~25的栗子:
let a = 25; // 25 等于 00000000000000000000000000011001
let b = ~a; // 将25的位反转 11111111111111111111111111100110
b // -26
~运算符大致等于-(x+1),~25等于-(25+1)等于-26。
2.indexOf
在JS中,indexOf方法在字符串中搜索指定的子字符串,如果找到就返回字符串所在的位置(从0开始),否则返回-1。indexOf(..)不仅能够得到子字符串的位置,还可以用来检查字符串是否包含指定的子字符串,相当于一个条件判断。
例如:
let a = 'hello world';
if (a.indexOf('lo') >= 0) { // true
}
if (a.indexOf('lo') != -1) { // true
}
if (a.indexOf('ol') < 0) { // true
}
if (a.indexOf('ol') == -1) { // true
}
>= 0和== -1这样的写法不是很好,称为“抽象滲漏”,意思是在代码中暴露了底层的实现细节,这里是指用-1作为失败时的返回值,这些细节应该被屏蔽掉。
现在大家应该明白~ 有什么用处了。~ 和 indexOf()一起可以将结果强制类型转换为true或false,这样就不用对搜索结果进行判断了。
let a = 'hello world';
~a.indexOf('lo') // -4
if (~a.indexOf('lo')) { // 找到匹配
}
~a.indexOf('ol') // 0,没找到匹配
!~a.indexOf('ol') // true
if (!~a.indexOf('lo')) { // 没找到匹配
}
如果indexOf()返回-1,~ 将其转换为假值0,其他情况一律转换为真值。