這篇文章不講一元運算子,也就是 + 、-、 *、 /、 =、 ||、 &&、 !這些,
位運算子是在數字底層(即表示數字的32個數位)進行操作的,
有符號整數使用 32 位的前 31 位表示整數值,第 32 位表示數值的符號,如 0 表示正,1 表示負,這一位稱為符號位,
正值以真正的二進制格式存盤,即 31位中的每一位都代表 2 的冪,第一位(稱為第 0 位)表示 2的0次冪,第二位表示 2的1次冪,依此類推,如果一個位是空的,則以0填充,相當于忽略不計,比如,數值18的二進制格式為00000000000000000000000000010010,或更精簡的 10010,后者是用到的 5 個有效位,決定了實際的值,
負值以一種稱為二補數(或補碼)的二進制編碼存盤,一個數值的二補數通過如下 3 個步驟計算得到:
(1) 確定絕對值的二進制表示(如,對于-18,先確定 18 的二進制表示);
(2) 找到數值的一補數(或反碼),換句話說,就是每個 0 都變成 1,每個 1 都變成 0;
(3) 給結果加 1,
基于上述步驟確定-18 的二進制表示,首先從 18 的二進制表示開始
0000 0000 0000 0000 0000 0000 0001 0010
然后,計算一補數,即反轉每一位的二進制值:
1111 1111 1111 1111 1111 1111 1110 1101
最后,給一補數加 1:
1111 1111 1111 1111 1111 1111 1110 1101
1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110
所以,-18 的二進制表示就是 11111111111111111111111111101110,
1. 按位非(~)
(~)是回傳數值的一補數,
let num1 = 25; // 二進制 00000000000000000000000000011001
let num2 = ~num1; // 二進制 11111111111111111111111111100110
console.log(num2); // -26
可以看出,(~)可以當做是這個數的絕對值取反減1的二進制數;
*** 小技巧: 對一個小數兩次按位非,可以得到取整效果,
console.log(~~2.5); // 2
2. 按位與(&)
按位與運算子用和號(&)表示,有兩個運算元,本質上,按位與就是將兩個數的每一個位對齊,然后基于真值表中的規則,對每一位執行相應的與操作,
tips: 是轉化成二進制的對應位數下的值是否一致;
let result = 25 & 3;
console.log(result); // 1
25 和 3 的按位與操作的結果是 1,為什么呢?看下面的二進制計算程序:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
& = 0000 0000 0000 0000 0000 0000 0000 0001
如上所示,25 和 3 的二進制表示中,只有第 0 位上的兩個數都是 1,于是結果數值的所有其他位都會以 0 填充,因此結果就是 1,
*** 小技巧:和1進行按位&操作來判斷其奇偶性,比如 num&1,若為1,則num是奇數;若為0,則num是偶數,
3. 按位或(|)
按位或運算子用管道符(|)表示,同樣有兩個運算元,按位或操作在至少一位是 1 時回傳 1,兩位都是 0 時回傳 0,
let result = 25 | 3;
console.log(result); // 27
可見 25 和 3 的按位或操作的結果是 27:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
| = 0000 0000 0000 0000 0000 0000 0001 1011
在參與計算的兩個數中,有 4 位都是 1,因此它們直接對應到結果上,二進制碼 11011 等于 27,
4. 按位異或(^)
按位異或用脫字符(^)表示,同樣有兩個運算元,
按位異或與按位或的區別是,它只在一位上是 1 的時候回傳 1(兩位都是 1 或 0,則回傳 0),
let result = 25 ^ 3;
console.log(result); // 26
可見,25 和 3 的按位異或操作結果為 26,如下所示:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
^ = 0000 0000 0000 0000 0000 0000 0001 1010
兩個數在 4 位上都是 1,但兩個數的第 0 位都是 1,因此那一位在結果中就變成了 0,其余位上的 1
在另一個數上沒有對應的 1,因此會直接傳遞到結果中,二進制碼 11010 等于 26,
5. 左移(<<)
左移運算子用兩個小于號(<<)表示,會按照指定的位數將數值的所有位向左移動,比如,如果數值 2(二進制 10)向左移 5 位,就會得到 64(二進制 1000000)

左移會保留它所運算元值的符號,比如,如果-2 左移 5 位,將得到-64,而不是正 64,
6. 有符號右移(>>)
有符號右移由兩個大于號(>>)表示,會將數值的所有 32 位都向右移,同時保留符號(正或負),有符號右移實際上是左移的逆運算,比如,如果將 64 右移 5 位,那就是 2,

7. 無符號右移(>>>)
無符號右移用 3 個大于號表示(>>>),會將數值的所有 32 位都向右移,
對于正數:無符號右移與有符號右移結果相同,仍然以前面有符號右移的例子為例,64 向右移動 5 位,會變成 2,
對于負數:因為負數是其絕對值的二補數,所以右移之后結果變得非常之大,
let num= -64; // 等于二進制 11111111111111111111111111000000
let result = num >>> 5; // 等于十進制 134217726
小技巧:
使用兩個嘆號(!!),相當于呼叫了轉型函式Boolean(),
指數運算子(**):ECMAScript 7 新增了指數運算子,Math.pow()現在有了自己的運算子**
## 雙非 !! console.log(!!"blue"); // true console.log(!!0); // false console.log(!!NaN); // false console.log(!!""); // false console.log(!!12345); // true ## 指數運算子** Math.pow(3, 2); // 3的平方: 9 3 ** 2; // 3的平方: 9 3 ** 3; // 3的三次方: 27
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/545606.html
標籤:JavaScript
上一篇:創建型:構造器模式
