JavaScript中7種位運算符在實戰的妙用

本篇文章帶大傢瞭解一下JavaScript中的7種位運算符,看看如何妙用這7種位運算符,希望對大傢有所幫助!

位運算符

ECMAScript 中的所有數值都以 IEEE 754 64 位格式存儲,但位操作並不直接應用到 64 位表示,而是先把值轉換為 32 位整數,再進行位操作,之後再把結果轉換為 64 位。

對開發者而言,就好像隻有 32 位整數一樣,因 為 64 位整數存儲格式是不可見的。既然知道瞭這些,就隻需要考慮 32 位整數即可。

有符號整數使用 32 位的前 31 位表示整數值。第 32 位表示數值的符號,如 0 表示正,1 表示負。這 一位稱為符號位(sign bit),它的值決定瞭數值其餘部分的格式。正值以真正的二進制格式存儲,即 31 位中的每一位都代表 2 的冪。第一位(稱為第 0 位)表示 20 ,第二位表示 21 ,依此類推。

如果一個位是空的,則以0填充,相當於忽略不計。比如,數值18的二進制格式為00000000000000000000000000010010, 或更精簡的 10010。後者是用到的 5 個有效位,決定瞭實際的值(如下圖所示)。

按位非 ~

按位非操作符用波浪符(~)表示,它的作用是返回數值的一補數。按位非是 ECMAScript 中為數 不多的幾個二進制數學操作符之一。看下面的例子:

let num1 = 25; //二進制 00000000000000000000000000011001
let num2 = ~num1; // 二進制 11111111111111111111111111100110
console.log(num2); // -26

這裡,按位非操作符作用到瞭數值 25,得到的結果是26。由此可以看出,按位非的最終效果是對 數值取反並減 1,就像執行如下操作的結果一樣:

let num1 = 25;
let num2 = -num1 - 1;
console.log(num2); // "-26"

實際上,盡管兩者返回的結果一樣,但位操作的速度快得多。這是因為位操作是在數值的底層表示 上完成的。

按位與 &

按位與操作符用和號(&)表示,有兩個操作數。本質上,按位與就是將兩個數的每一個位對齊, 然後基於真值表中的規則,對每一位執行相應的與操作。

按位與操作在兩個位都是 1 時返回 1,在任何一位是 0 時返回 0。 下面看一個例子,我們對數值 25 和 3 求與操作,如下所示:

let result = 25 & 3;
console.log(result); // 1 25 和 3 的按位與操作的結果是 1。

為什麼呢?看下面的二進制計算過程:

如上圖所示,25 和 3 的二進制表示中,隻有第 0 位上的兩個數都是 1。於是結果數值的所有其他位都 會以 0 填充,因此結果就是 1。

按位或 |

按位或操作符用管道符(|)表示,同樣有兩個操作數。按位或遵循如下真值表:

按位或操作在至少一位是 1 時返回 1,兩位都是 0 時返回 0。 仍然用按位與的示例,如果對 25 和 3 執行按位或,代碼如下所示:

let result = 25 | 3;
console.log(result); // 27

可見 25 和 3 的按位或操作的結果是 27:

在參與計算的兩個數中,有 4 位都是 1,因此它們直接對應到結果上。二進制碼 11011 等於 27。

按位異或 ^

按位異或用脫字符(^)表示,同樣有兩個操作數。下面是按位異或的真值表:

按位異或與按位或的區別是,它隻在一位上是 1 的時候返回 1(兩位都是 1 或 0,則返回 0)。 對數值 25 和 3 執行按位異或操作:

let result = 25 ^ 3;
console.log(result); // 26

可見,25 和 3 的按位異或操作結果為 26,如下所示:

兩個數在 4 位上都是 1,但兩個數的第 0 位都是 1,因此那一位在結果中就變成瞭 0。其餘位上的 1 在另一個數上沒有對應的 1,因此會直接傳遞到結果中。二進制碼 11010 等於 26。(註意,這比對同樣 兩個值執行按位或操作得到的結果小 1。)

左移 <<

左移操作符用兩個小於號(<<)表示,會按照指定的位數將數值的所有位向左移動。比如,如果數 值 2(二進制 10)向左移 5 位,就會得到 64(二進制 1000000),如下所示:

let oldValue = 2; // 等於二進制 10
let newValue = oldValue << 5; // 等於二進制 1000000,即十進制 64

註意在移位後,數值右端會空出 5 位。左移會以 0 填充這些空位,讓結果是完整的 32 位數值(見下圖)。

註意,左移會保留它所操作數值的符號。比如,如果-2 左移 5 位,將得到-64,而不是正 64。

有符號右移 >>

有符號右移由兩個大於號(>>)表示,會將數值的所有 32 位都向右移,同時保留符號(正或負)。 有符號右移實際上是左移的逆運算。比如,如果將 64 右移 5 位,那就是 2:

let oldValue = 64; // 等於二進制 1000000
let newValue = oldValue >> 5; // 等於二進制 10,即十進制 2

同樣,移位後就會出現空位。不過,右移後空位會出現在左側,且在符號位之後(見圖 3-3)。 ECMAScript 會用符號位的值來填充這些空位,以得到完整的數值。

無符號右移 >>>

無符號右移用 3 個大於號表示(>>>),會將數值的所有 32 位都向右移。對於正數,無符號右移與 有符號右移結果相同。仍然以前面有符號右移的例子為例,64 向右移動 5 位,會變成 2:

let oldValue = 64; // 等於二進制 1000000 
let newValue = oldValue >>> 5; // 等於二進制 10,即十進制 2

對於負數,有時候差異會非常大。與有符號右移不同,無符號右移會給空位補 0,而不管符號位是 什麼。對正數來說,這跟有符號右移效果相同。但對負數來說,結果就差太多瞭。無符號右移操作符將負數的二進制表示當成正數的二進制表示來處理。因為負數是其絕對值的二補數,所以右移之後結果變 得非常之大,如下面的例子所示:

let oldValue = -64; // 等於二進制 11111111111111111111111111000000
let newValue = oldValue >>> 5; // 等於十進制 134217726

在對-64 無符號右移 5 位後,結果是 134 217 726。這是因為-64 的二進制表示是 1111111111111111111 1111111000000,無符號右移卻將它當成正值,也就是 4 294 967 232。把這個值右移 5 位後,結果是 00000111111111111111111111111110,即 134 217 726。

實戰中的妙用

1.判斷奇偶數

// 偶數 & 1 = 0
// 奇數 & 1 = 1
console.log(2 & 1) // 0
console.log(3 & 1) // 1

2. 使用^來完成值的交換

let a = 2
let b = 5
a ^= b
b ^= a
a ^= b
console.log(a) // 5
console.log(b) // 2

3. 使用~進行判斷

// 常用判斷
if (arr.indexOf(item) > -1) {
    // code
}
// 按位非    ~-1 = -(-1) - 1 取反再 -1
if (~arr.indexOf(item)) {
    // code
}

4. 使用&、>>、|來完成rgb值和16進制顏色值之間的轉換

/**
 * 16進制顏色值轉RGB
 * @param  {String} hex 16進制顏色字符串
 * @return {String}     RGB顏色字符串
 */
  function hexToRGB(hex) {
    var hexx = hex.replace('Id', '0x')
    var r = hexx >> 16
    var g = hexx >> 8 & 0xff
    var b = hexx & 0xff
    return `rgb(${r}, ${g}, ${b})`
}
 
/**
 * RGB顏色轉16進制顏色
 * @param  {String} rgb RGB進制顏色字符串
 * @return {String}     16進制顏色字符串
 */
function RGBToHex(rgb) {
    var rgbArr = rgb.split(/[^\d]+/)
    var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3]
    return 'Id'+ color.toString(16)
}
// -------------------------------------------------
hexToRGB('Idffffff')               // 'rgb(255,255,255)'
RGBToHex('rgb(255,255,255)')      // 'Idffffff'

5. 使用|、~、>>、<<、>>>來取整

console.log(~~ 3.1415)    // 3
console.log(3.1415 >> 0)  // 3
console.log(3.1415 << 0)  // 3
console.log(3.1415 | 0)   // 3
// >>>不可對負數取整
console.log(3.1415 >>> 0)   // 3

【相關推薦:】

以上就是聊聊JavaScript中的7種位運算符,看看在實戰中如何妙用?的詳細內容,更多請關註php中文網其它相關文章!

參考地址:http://www.php.cn//js-tutorial-487096.html

到此這篇關於JavaScript中7種位運算符在實戰的妙用的文章就介紹到這瞭,更多相關JS位運算符實戰內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: