cc
cc copied to clipboard
14.使用 ~ 和 indexOf 来判断一个元素是否在数组中
引子
判断一个元素是否在数组中,代码很简单,也就一个 if 判断了事
var t = {val:2};
if([1,2,3,4,5].indexOf(t.val) >= 0){
alert('Yes');
}
PS:indexOf 来自 ES5 ,IE9一下不支持
使用 ~ 符号却能简化判断语句,如下:
if( ~[1,2,3,4,5].indexOf(t.val) ){
// other things
}
Why
如果一个元素存在于数组中,indexOf() 则返回它的索引;不存在,返回 -1。 细节怎么的不重要,因为 ~ 就是个位操作符(按位非),反转操作数的比特位,只有-1才会返回0。
More
整数在 js 中是被符号化的,意味着最左侧的一个bit用来表示符号位;也就是一个表示帧数负数的标记,1开始表示为负数,32位表示如下
1 : 00000000000000000000000000000001
2 : 00000000000000000000000000000010
3 : 00000000000000000000000000000011
15: 00000000000000000000000000001111
对应的负数:
-1 : 11111111111111111111111111111111
-2 : 11111111111111111111111111111110
-3 : 11111111111111111111111111111101
-15: 11111111111111111111111111110001
二进制中正负数原码 反码不必多说。
下面简单的二进制计算 来展示 -1 + +1 是如何运算的
00000000000000000000000000000001 +1
+ 11111111111111111111111111111111 -1
-------------------------------------------
= 00000000000000000000000000000000 0
以及 -15 + +15
00000000000000000000000000001111 +15
+ 11111111111111111111111111110001 -15
--------------------------------------------
= 00000000000000000000000000000000 0
从最右侧开始相加,1+1=2 也就是 10 把1向前借位,然后一直循环到最左侧,直到最后一个借位的 1 无处可去,于是就 溢出 overflow 了,然后就丢失了,我们只剩下一堆的 0 ,结果于是就是 0
总之
-1 这个数是为一个其二进制码全是 1 的数字,因此使用 ~ 这个按位取反符号后,它的所有二进制数位全部反转。
所以这大段的文其实就只是解释了 按位取反后只有-1才会返回0。
这个涉及到代码的可读性,不太建议用 ~,毕竟不常用,其他人读到这行代码可能会被卡住
我也用过~一段时间,后来就不用了