~,&,|,^等位运算符在JavaScript中的一些应用

最近看到一些代码中用到了位运算符,表示好奇。在前端开发中有哪些使用呢。来总结一下~

注:使用为运算符的代码可读性变差,建议斟酌使用。有问题欢迎指正或者补充

应用

判断奇偶数

num & 1 === 1 // num 为奇数

num & 1 === 0 // num 为偶数

因为二进制的奇数最低位是1,偶数最低位是0,& 1运算后可以判断奇偶(&见下方)

效率

与 % 2来判断奇偶速度差不多

取整

类似于parseInt

~~3.14159 // 3

3.14159 >> 0 //3

3.14159 >>> 0 //3

3.14159 | 0 // 3

‘>>>’不用于对负数取整,其他都可以

效率

1
2
3
4
5
6
7
8
9
10
11
12
13
var count = 5000000
var num = 1.51
console.time('parseInt');
for (var i = count; i > 0; i--) {
parseInt(num);
}
console.timeEnd('parseInt'); //51.822998046875ms

console.time('~~');
for (var i = count; i>0; i--) {
~~num;
}
console.timeEnd('~~'); //14.94580078125ms

位操作符 效率高很多,只是可读性差一些

比较值是否相等

相当于==

^也会将字符串类型的数字转化为数字再进行运算

1 ^ 1 // 0

相等返回0 不相等返回非0

效率

与 == 比较 ^ 的效率高,但可读性差一些

变量值为数字时,完成值的交换

a ^= b 就是 a = a ^ b

1
2
3
4
5
6
var a = 1 , b = 2
a ^= b
b ^= a
a ^= b
console.log(a) // 2
console.log(b) // 1

过程

1
2
3
4
5
6
7
8
9
10
11
12
a.toString(2) // 1 => 1
b.toString(2) // 2 => 10
a = a ^ b
//根据^运算后a此时为二进制 11 也就是二进制的 3
a.toString(2) // 3 => 11
b.toString(2) // 2 => 10
b = b ^ a
//根据^运算后b此时为二进制 1 也就是十进制的 1,a成功赋值给b
a.toString(2) // 3 => 11
b.toString(2) // 1 => 1
a = a ^ b
//根据^运算后b此时为二进制 10 也就是十进制的 2,b成功赋值给a

效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var count = 5000000
var num = 1.51
console.time('临时变量');
for (var i = count; i > 0; i--) {
var t,a = 1,b = 2;
t = a;
a = b;
b = t;
}
console.timeEnd('临时变量'); //14.343994140625ms

console.time('^');
for (var i = count; i>0; i--) {
var d = 1, g = 2
d ^= g
g ^= d
d ^= g
}
console.timeEnd('^'); //13.31396484375ms

与临时变量的方法相比效率差不多 但^只能用于数字类型

rgb值和16进制颜色值的转换

16进制转rgb

1
2
3
4
5
6
7
function hexToRGB(hex){
var hex = hex.replace("#","0x"),
r = hex >> 16,
g = hex >> 8 & 0xff,
b = hex & 0xff;
return "rgb("+r+","+g+","+b+")";
}

rgb转16进制

1
2
3
4
5
function RGBToHex(rgb){
var rgbArr = rgb.split(/[^\d]+/),
color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3];
return "#"+color.toString(16);
}

rgb值和16进制颜色值转换这里我不太能理解,猜想应该是rgb值和16进制之间有对应关系

详解

位运算NTO ‘ ~ ’

W3C中的说法

定义:ECMAScript 中为数不多的与二进制算术有关的运算符之一

处理过程:

  • 把运算数转换成 32 位数字
  • 把二进制数转换成它的二进制反码
  • 把二进制数转换成浮点数

实质上是对数字求负,然后减 1 (-x-1)

由于二进制都是0 1组成 所以转化成二进制以后 小数部分就不存在了

1
2
3
4
5
6
7
8
9
10
11
console.log('~null: ', ~null);       // => -1
console.log('~undefined: ', ~undefined); // => -1
console.log('~0: ', ~0); // => -1
console.log('~{}: ', ~{}); // => -1
console.log('~[]: ', ~[]); // => -1
console.log('~(1/0): ', ~(1/0)); // => -1
console.log('~false: ', ~false); // => -1
console.log('~true: ', ~true); // => -2
console.log('~3: ', ~3); // => -4
console.log('~3.3: ', ~3.3); // => -4
console.log('~(-2.999): ', ~(-2.999)); // => 1

那么~~就是对数字求负减一后再求负减1 (-(-x-1))-1 也就可以用于取整

1
2
3
4
5
6
7
8
9
10
11
console.log('~~null: ', ~~null);       // => 0
console.log('~~undefined: ', ~~undefined); // => 0
console.log('~~0: ', ~~0); // => 0
console.log('~~{}: ', ~~{}); // => 0
console.log('~~[]: ', ~~[]); // => 0
console.log('~~(1/0): ', ~~(1/0)); // => 0
console.log('~~false: ', ~~false); // => 0
console.log('~~true: ', ~~true); // => 1
console.log('~~3: ', ~~3); // => 3
console.log('~~3.3: ', ~~3.3); // => 3
console.log('~~(-2.999): ', ~~(-2.999)); // => -2

位运算AND ’ & ‘

W3C中的说法

定义:对数字的二进制形式进行运算。它把每个数字中的数位对齐,然后用下面的规则对同一位置上的两个数位进行 AND 运算

规则:两个都为1才是1

第一个数字中的位数 第二个数字中的位数 结果
1 1 1
1 0 0
0 1 0
0 0 0

例如:

1
2
var num = 1651 & 1
console.log(num) // 1

运算过程,两个数字转为二进制(32位)然后按照上面的规则进行&运算

1
2
3
4
 1651 = 0000 0000 0000 0000 0000 0110 0111 0011 
1 = 0000 0000 0000 0000 0001 0000 0000 0001
---------------------------------------------
AND = 0000 0000 0000 0000 0000 0000 0000 0001

位运算 OR ’ | ‘

W3C中的说法

直接对数字的二进制形式进行运算。在计算每位时,OR 运算符采用下列规则:一个为1则是1

第一个数字中的数位 第二个数字中的数位 结果
1 0 1
0 1 1
1 1 1
0 0 0

例如

1
2
var iResult = 25 ^ 0
alert(iResult); //输出 "25"

运算过程

1
2
3
4
25 = 0000 0000 0000 0000 0000 0000 0001 1001
0 = 0000 0000 0000 0000 0000 0000 0000 0000
--------------------------------------------
OR = 0000 0000 0000 0000 0000 0000 0001 1001

1001转10进制为25

位运算 XOR ‘ ^ ’

W3C中的说法

定义:直接对二进制形式进行运算。XOR 不同于 OR,当只有一个数位存放的是 1 时,它才返回 1

规则

第一个数字中的数位 第二个数字中的数位 结果
1 1 0
0 1 1
1 0 1
0 0 0

例如:

1
2
var iResult = 25 ^ 3;
alert(iResult); //输出 "26"

过程:

1
2
3
4
5
 25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010
二进制代码 11010 等于 十进制26

左移运算<<、有符号右移运算>>、无符号右移运算>>>

这里我就直接贴链接了,W3C任意门

参考

https://www.deanhan.cn/js-bitwise-operation.html
https://segmentfault.com/a/1190000003731938

------ 本文结束------
0%