最近看到一些代码中用到了位运算符, 表示好奇. 在前端开发中有哪些使用呢. 来总结一下~
注: 使用为运算符的代码可读性变差, 建议斟酌使用. 有问题欢迎指正或者补充
应用
判断奇偶数
- 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
'>>>'不用于对负数取整, 其他都可以
效率
- 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
- var a = 1 , b = 2
- a ^= b
- b ^= a
- a ^= b
- console.log(a) // 2
- console.log(b) // 1
过程
- 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
效率
- 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
- 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 进制
- 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 组成 所以转化成二进制以后 小数部分就不存在了
- 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 也就可以用于取整
- 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 |
例如:
- var num = 1651 & 1
- console.log(num) // 1
运算过程, 两个数字转为二进制 (32 位) 然后按照上面的规则进行 & 运算
- 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 |
例如
- var iResult = 25 ^ 0
- alert(iResult); // 输出 "25"
运算过程
- 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 |
例如:
- var iResult = 25 ^ 3;
- alert(iResult); // 输出 "26"
过程:
- 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
来源: https://juejin.im/post/5bc42c5c6fb9a05d3a4b5f59