概述
作用速度快,都作用于32位整数,二进制位运算符用于直接对二进制位进行计算
二进制运算符有那些
| 运算符 | 表达式 | 备注 |
|---|---|---|
| 按位与 | a & b | 若两个二进制位都为1,则结果为1,否则为0 |
| 按位或 | a | b | 若两个二进制位都为0,则结果为0,否则为1 |
| 按位异或 | a ^ b | 若两个二进制位不相同,则结果为1,否则为0 |
| 按位非 | ~ a | 反转操作数的二制位,即0变成1,1变成0。 |
| 左移 | a << b | 将 a 的二进制形式向左移 b (< 32) 位,右边用0填充。 |
| 有符号右移 | a >> b | 将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。 |
| 无符号右移 | a >>> b | 将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。 |
常用应用
判断数字奇偶性
4 & 1 === 0
5 & 1 === 1
权限控制
通过 <<,&,| 进行权限控制
ready = 1 // 读的权限(1)
write = 1 << 2 // 写的权限(10)
execute = 1 << 3 // 执行权限(100)
// 假如有读和写的权限
permissions = ready | write // (11)
if (ready & permissons){ // 1 & 11 => 1
}
if (write & permissons) { // 10 & 11 => 4
}
if (execute & permissons) { 100 & 11 => 0
}
// vue中的PatchFlags
export const enum PatchFlags {
TEXT = 1,
CLASS = 1 << 1,
STYLE = 1 << 2,
PROPS = 1 << 3,
FULL_PROPS = 1 << 4,
HYDRATE_EVENTS = 1 << 5,
STABLE_FRAGMENT = 1 << 6,
KEYED_FRAGMENT = 1 << 7,
UNKEYED_FRAGMENT = 1 << 8,
NEED_PATCH = 1 << 9,
DYNAMIC_SLOTS = 1 << 10,
DEV_ROOT_FRAGMENT = 1 << 11,
HOISTED = -1,
BAIL = -2
}
const flag = TEXT | CLASS
if (flag & TEXT) { ... }
数字取整
使用~, >>, <<, >>>, |来取整,因为都是作用在32位的整数上,小数会直接忽略
console.log(~~ 1.22) // 1
console.log(1.22 >> 0) // 1
console.log(1.22 << 0) // 1
console.log(1.82 | 0) // 1
// >>>不可对负数取整
console.log(3.45 >>> 0) // 3
将 -1 转为 0
// indexOf,lastIndexOf
~'abc'.indexOf('n') // 0 ~符可以 表示 -(x + 1)=> -(-1+1) => 0
位运算不是为了装逼
上面概述里面就讲了,位运算是作用二进制,速度快,下面实测
console.time('|0向下取整')
for(var i = 0; i < 1000000; i ++){
i/7 | 0
}
console.timeEnd('|0向下取整')
console.time('Math.floor')
for(var i = 0; i < 1000000; i ++){
Math.floor(i / 3)
}
console.timeEnd('Math.floor')
var b = 1 << 3
var c = a | b
console.time('位运算权限')
for(var i = 0; i < 1000000; i ++){
if(a & c){}
}
console.timeEnd('位运算权限')
console.time('indexOf')
for(var i = 0; i < 1000000; i ++){
if([4, 8].indexOf(4) > -1) {}
}
console.timeEnd('indexOf')
位运算在性能上有一定的效果,装逼不存在的,当然这点性能,在日常开发基本无用,对于算法追求极速,还是不错的;不过通过位运算达到的极简优雅写法还是很吸引人的