什么是JavaScript位操作符?🤔
其实 JavaScript 位操作符是数值的底层操作,用来操作内存中表示数据的比特位,我们都知道 JavaScript 中的所有数值都是以 64 位格式存储的数据,我们要说的位操作符不会直接运用到64位表示,而是先将值转换为 32 位整数进行位操作,再转换为 64 位
有符号整数使用 32 位的前 31 位表示整数值,第 32 位(符号位)表示数值的符号(0表示正 ,1表示负)
如果是一个正值,那么会以真正的二进制格式存储,也就是说 31 位中的每一位都代表这 2 的幂,空位补零(忽略不计),比如 十进制数 18 的二进制格式为:00000000000000000000000000010010,这还能看?😅,我们简写一下:10010,我们使用这五个有效位就可以了
如果十进制数为负数的话,会以一种 二补数 的二进制编码存储:
我们来演示一下:
# 确定绝对值的二进制表示
00000000000000000000000000010010
# 找到数值的一补数
11111111111111111111111111101101
# 给结果加一
11111111111111111111111111101110
所以 -18 的二进制数是 101110,把负值输出为一个二进制字符串的时候,我们会得到一个前面加了减号的绝对值,不过转换过程会求得二补数,只是以一种更加符合逻辑的形式表现出来,我们上代码验证一下:
如果是非数值的话,JavaScript 会自动调用 Number()
函数进行处理,处理之后进行位操作
BUG:在对 JavaScript 中的数值使用位操作符的时候,在后台 64 位数值会转换为 32 位数值,然后执行位操作,最后再把 32 位数值转换为 64 位数值存储起来,这个转换的过程也导致了一个BUG,不过也不能叫BUG,可以说是一个副作用吧,当我们对 NaN
和 Infinity
执行位操作的时候会被当成 0 处理
按位非操作符的功能是返回数值的一补数
let num = 18
let num2 = ~num
console.log(num2)
// -19
这不就是取反减一嘛🤔
let num = 18
let num2 = ~num
console.log(num2)
// -19
let num = 18
let num2 = -num - 1
console.log(num2)
不过这可没有 ~
位操作符在底层执行的快
按位与可操作俩个数值,基于真值表
进行比较并操作:
不难看出按位与操作符俩个位都为 1 返回 1,有一个位为 0 ,则返回 0
let num = 25 & 3
console.log(num)
// 1
25 = 00000000000000000000000000011001
3 = 00000000000000000000000000000011
结果:00000000000000000000000000000001
依旧是比较真值表:有一位是 1 返回 1,俩位都是 0 ,返回 0
let num = 25 | 3
console.log(num)
// 27
25 = 00000000000000000000000000011001
3 = 00000000000000000000000000000011
结果:00000000000000000000000000011011
还是我们的真值表:只有一位为 1 ,返回 1,俩位都是 1 或者 0 ,返回 0
let num = 25 ^ 3
console.log(num)
// 26
25 = 00000000000000000000000000011001
3 = 00000000000000000000000000000011
结果:00000000000000000000000000011010
按照指定位数将数值的所有位向左移
let num = 2
let new_num = num << 5
console.log(new_num)
// 64
#()中的为符号位
2 = (0)0000000000000000000000000000010
# 向左移5位 -- 空位补零
(0)00000000000000000000000010[00000] = 64
// 左移会保留它所操作数值的符号
let num = -2
let new_num = num << 5
console.log(new_num)
// -64
这没有什么可说的,值得注意的一点就是右移后空位出现在左侧的符号位之后,而 JavaScript 会使用符号位的值来填充这些空位,得到完整的数值
如果数值是一个正数的话,那么它和>>
是一样的,一但是负数,>>>
则会将负数的二进制表示当成正数的二进制来进行处理,但负数是数值绝对值的二补数,所以右移之后结果会非常之大:
let num = -2
let new_num = num >>> 5
console.log(new_num)
// 134217727