在数组中查找某个值时,可以使用indexOf()
方法
if(arr.indexOf(item) > -1){
// 在arr数组中存在item值
}
if(arr.indexOf(item) === -1){
// 在arr数组中不存在item值
}
使用位运算符~
将代码进一步简化,当位运算符~
右侧的变量不为-1时,返回true,否则返回false
if(~arr.indexOf(item)){
// 在arr数组中存在item值
}
if(!~arr.indexOf(item)){
// 在arr数组中不存在item值
}
位运算符 (参考文章)
位运算符主要以二进制规则进行运算并且按位运算符是把操作数看作一系列单独的位,而不是一个数字值。
什么是 ‘位’ :
数值或字符在内存内都是被存储为0和1的序列,每个0和1被称之为1个位,比如说10进制数据2在计算机内被存储为 0 0 0 0 0 0 1 0(此处以一字节为例),当我们将内存内的位值改变之后,这个值代表的意义也就变了,比如把2前移动一位, 现在存储单元里面变成了0 0 0 0 0 1 0 0,这个值表示的是十进制的4,这也就是按位操作符的运算原理。
js中的位运算符有七个,分为两类:
- 逻辑位运算符,包括按位与
&
、按位或|
、按位异或^
、按位非~
- 移位运算符,包括左移
<<
、右移>>
、无符号右移>>>
按位与&
同一位上都为1(真)时才为1(真),其余为0(假)
例如:
var a = 1; // 转二进制 0001
var b = 2; // 转二进制 0010
console.log(a & b); // 0000 转十进制 0
按位或|
同一位上都为0(假)时才为0(假),其余为1(真)
例如
var a = 1; // 转二进制 0001
var b = 2; // 转二进制 0010
console.log(a | b); // 0011 转十进制 3
按位异或^
同一位上数值相同则为0(假),不同则为1(真)
例如
var a = 1;// 转二进制 0001
var b = 3;// 转二进制 0010
console.log(a ^ b);// 0011 转十进制 3
按位非~
(理解起来稍微有点绕 这篇文章解释的很好)
要想更好的理解按位非运算符,需要先搞清楚计算机在内存中的计算和存储方式,可参考文章
按位非~
的逻辑是按位取反,操作的是二进制数
例1:对2进行~2操作
1.2(原码)的二进制为00000010
2.~2按位取反后为11111101(包括符号位也取反)
3.由于计算机中所有有符号数都是以补码的形式存在,所以进行转换
4.11111101的反码为10000010(符号位不变)
5.10000010的补码为10000011(在反码的基础上+1)
6.10000011的十进制为-3
例2:对0进行~0操作
1.0(原码)的二进制为00000000
2.~0按位取反后为11111111
3.由于计算机中所有有符号数都是以补码的形式存在,所以进行转换
4.11111111的反码为1000000
5.1000000的补码为1000001
6.1000001的十进制为-1
由上述两个例子可知,按位非操作符的本质其实就是操作数的负值减1
~2 = -2-1 = -3
~0 = -0-1 = -1
所以在使用indexOf操作符判断数组中是否存在某值时,可以用按位非~
来辅助判断,是因为~-1 = 1 - 1 = 0
,而其他数的取反操作不等于0。
左移<<
将操作数的所有位向左移动指定位数,如i << 1
表示把 i 的所有二进制位左移一位,符号位不变,按位左移,右边补0
1 << 2 (操作数 << 左移位数)
符号位不变,按位左移,右边补0
|0000 0001|
-----------------
00 |0000 0100| // 左移2位,左边被挤掉2个0,右边补两个0
得到结果00000100
,转换为十进制就是4
回想十进制,十进制左移一位为乘10(如123,左移一位后补零即为1230),右移一位为除以10
同理二进制,二进制左移一位为乘2,右移一位为除以2,当左移n位时相当于乘2的n次方
右移>>
将操作数的所有位向右移动指定位数,如i >> 1
表示把 i 的所有二进制位右移一位,符号位为0,则左边补0,符号位为1,则左边补1
无符号右移>>
将操作数的所有位向右移动指定位数,如i >> 1
表示把 i 的所有二进制位右移一位,符号位不变,左边补0
2 >> 2 (操作数 >> 右移位数)
符号位不变,按位右移,左边补0
|0000 0010|
-----------------
|0000 0000|10 // 右移2位,右边被挤掉'10',左边补两个0
得到结果00000000
,转换为十进制就是0