越努力,越幸运,做个ccode~

0%

位操作符与逻辑操作符

前言

在判断分支中使用符号”&“和”&&”作为逻辑判断是经常见的,但是这两者又有什么区别呢?
他们分别代表的位运算符和逻辑运算符又有什么区别呢?

位操作符

位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值

补充知识点 负数存储

负数同样是以二进制存储 但使用的格式是二进制补码

计算一个数值(负数)的二进制补码,需要经过三个步骤
1)求这个数值绝对值的二进制码 例如 要求 -18的二进制补码 先求出18的二进制码
2)求二进制反码 即将0换为1 1换为0
3)最后二进制反码 + 1

1 按位非( ~ )

执行按位非的结果就是返回数值的反码

~25 = -26
~10 = -11
~-10 = 9

然后我们发现了规律 好像就是 这个数的负数减一
我们知道一个数的负数二进制存储是 该数取反 +1 那么很容易推出一个数的反码就是 该数的负数 -1

2 按位与( & )

按位与只有在两个数值的对应位都是1时才返回1 任何一位是0 结果都是0

0b110 & 0b011  // 2
25 & 3     // 1

3 按位或( | )

只有两个数值的对应位都是0的情况下才返回0 否则返回1

0b110 | 0b011  // 0b111 => 7
0b001 | 0b011  // 0b011 => 3

4 按位异或( ^ )

这两个数值的对应位上有一个1时才返回1 否则返回0

0b011 ^ 0b0101    // 0b0110 => 6
25 ^ 3   // 26 

异或的应用

任何数和0异或得到他本身 和自己异或得到0

15 ^ 0   // 15
15 ^ 15  // 0

5 左移( << )

这个操作符会将所有位向左移动指定的位数
向左移动后原始值的右侧会多出空位,左移操作会用0来填充这些空位
以便得到的结果是一个32位的二进制数

2 << 5  // 64   10 => 1000000

需要注意的是,左移不会影响操作数的符号位

-2 << 5 // - 64 

左移的应用

左移一位相当于在右边补一个0 相当于原数 * 2

2 << 1  // 4
5 << 1  // 10

6 有符号的右移( >> )

有符号的右移会将所有位向右移动 但保留符号位
有符号的右移与左移相反

64 >> 5   // 2   1000000 => 10

移动过程中也会出现空位 不过空位是出现在原数值的左侧 符号位的右侧 而此时ES会用符号位的值来填补空位

7 无符号的右移( >>> )

这个操作会将所有的32位都像右移动 即符号位也右移
无符号右移是以0来填充空位
所以,对正数来说, 无符号的右移与有符号右移的结果相同

64 >> 5   // 2
64 >>> 5  // 2

但对于负数来说,情况就不一样了

-64 >>> 5  //  134217726

因为负数是以其绝对值的二进制补码表示,无符号右移会把这个二进制当做正数表示,所以会导致右移后的结果非常大

逻辑操作符

逻辑运算符用于进行逻辑运算的,他的返回值只有true和false

逻辑非( ! )

逻辑非首先会操作数转换为对应的布尔值,然后对其求反

我们知道js中有五大falsy值 分别是 NaN 0 空字符串 undefined null
所以对这五个falsy值取反得到的是true

!undefined  // true
!null       // true
!''         // true
!0          // true
!NaN        // true

需要注意的是js中 空数组和空对象对应的布尔值都是true

!{}  // false
![]  // false

使用两次逻辑非就可以得到一个数的布尔值 相当于Boolean()函数

!!{}  // true
!!0   // false
!!undefined // false

逻辑或( || )

两个表达式只要有一个是true 那么结果就是true
短路操作符 如果第一个表达式结果是true 那么就不会看第二个表达式

2 > 3 || 3 < 5    // true
2 > 3 || 3 > 5    // false
false || true     // true
false || false    // false

逻辑与( && )

只有两个表达式结果都为true 结果才为true 否则为false
短路操作符 如果第一个表达式是false 那么直接返回false 不会看第二个表达式

2 > 3 && 3 < 5    // false
2 > 3 && 3 > 5    // false
2 < 3 && 3 < 5    // true
false && true     // true
true && true      // true