溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

發(fā)布時(shí)間:2022-01-06 13:00:06 來(lái)源:億速云 閱讀:114 作者:柒染 欄目:web開發(fā)

本篇文章為大家展示了JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

位運(yùn)算符

操作符用于數(shù)值的底層操作,也就是操作內(nèi)存中表示數(shù)據(jù)的比特(位)。

ECMAScript 中的所有數(shù)值都以 IEEE 754 64 位格式存儲(chǔ),但位操作并不直接應(yīng)用到 64 位表示,而是先把值轉(zhuǎn)換為 32 位整數(shù),再進(jìn)行位操作,之后再把結(jié)果轉(zhuǎn)換為 64 位。

對(duì)開發(fā)者而言,就好像只有 32 位整數(shù)一樣,因 為 64 位整數(shù)存儲(chǔ)格式是不可見的。既然知道了這些,就只需要考慮 32 位整數(shù)即可。

有符號(hào)整數(shù)使用 32 位的前 31 位表示整數(shù)值。第 32 位表示數(shù)值的符號(hào),如 0 表示正,1 表示負(fù)。這 一位稱為符號(hào)位(sign bit),它的值決定了數(shù)值其余部分的格式。正值以真正的二進(jìn)制格式存儲(chǔ),即 31 位中的每一位都代表 2 的冪。第一位(稱為第 0 位)表示 20 ,第二位表示 21 ,依此類推。

如果一個(gè)位是空的,則以0填充,相當(dāng)于忽略不計(jì)。比如,數(shù)值18的二進(jìn)制格式為00000000000000000000000000010010, 或更精簡(jiǎn)的 10010。后者是用到的 5 個(gè)有效位,決定了實(shí)際的值(如下圖所示)。

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

按位非

按位非操作符用波浪符(~)表示,它的作用是返回?cái)?shù)值的一補(bǔ)數(shù)。按位非是 ECMAScript 中為數(shù) 不多的幾個(gè)二進(jìn)制數(shù)學(xué)操作符之一??聪旅娴睦樱?/p>

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

這里,按位非操作符作用到了數(shù)值 25,得到的結(jié)果是?26。由此可以看出,按位非的最終效果是對(duì) 數(shù)值取反并減 1,就像執(zhí)行如下操作的結(jié)果一樣:

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

實(shí)際上,盡管兩者返回的結(jié)果一樣,但位操作的速度快得多。這是因?yàn)槲徊僮魇窃跀?shù)值的底層表示 上完成的。

按位與 &

按位與操作符用和號(hào)(&)表示,有兩個(gè)操作數(shù)。本質(zhì)上,按位與就是將兩個(gè)數(shù)的每一個(gè)位對(duì)齊, 然后基于真值表中的規(guī)則,對(duì)每一位執(zhí)行相應(yīng)的與操作。

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

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

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

為什么呢?看下面的二進(jìn)制計(jì)算過程:

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

如上圖所示,25 和 3 的二進(jìn)制表示中,只有第 0 位上的兩個(gè)數(shù)都是 1。于是結(jié)果數(shù)值的所有其他位都 會(huì)以 0 填充,因此結(jié)果就是 1。

按位或

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

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

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

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

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

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

在參與計(jì)算的兩個(gè)數(shù)中,有 4 位都是 1,因此它們直接對(duì)應(yīng)到結(jié)果上。二進(jìn)制碼 11011 等于 27。

按位異或 ^

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

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

按位異或與按位或的區(qū)別是,它只在一位上是 1 的時(shí)候返回 1(兩位都是 1 或 0,則返回 0)。 對(duì)數(shù)值 25 和 3 執(zhí)行按位異或操作:

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

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

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

兩個(gè)數(shù)在 4 位上都是 1,但兩個(gè)數(shù)的第 0 位都是 1,因此那一位在結(jié)果中就變成了 0。其余位上的 1 在另一個(gè)數(shù)上沒有對(duì)應(yīng)的 1,因此會(huì)直接傳遞到結(jié)果中。二進(jìn)制碼 11010 等于 26。(注意,這比對(duì)同樣 兩個(gè)值執(zhí)行按位或操作得到的結(jié)果小 1。)

左移 <<

左移操作符用兩個(gè)小于號(hào)(<<)表示,會(huì)按照指定的位數(shù)將數(shù)值的所有位向左移動(dòng)。比如,如果數(shù) 值 2(二進(jìn)制 10)向左移 5 位,就會(huì)得到 64(二進(jìn)制 1000000),如下所示:

let oldValue = 2; // 等于二進(jìn)制 10
let newValue = oldValue << 5; // 等于二進(jìn)制 1000000,即十進(jìn)制 64

注意在移位后,數(shù)值右端會(huì)空出 5 位。左移會(huì)以 0 填充這些空位,讓結(jié)果是完整的 32 位數(shù)值(見下圖)。

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

注意,左移會(huì)保留它所操作數(shù)值的符號(hào)。比如,如果-2 左移 5 位,將得到-64,而不是正 64。

有符號(hào)右移 >>

有符號(hào)右移由兩個(gè)大于號(hào)(>>)表示,會(huì)將數(shù)值的所有 32 位都向右移,同時(shí)保留符號(hào)(正或負(fù))。 有符號(hào)右移實(shí)際上是左移的逆運(yùn)算。比如,如果將 64 右移 5 位,那就是 2:

let oldValue = 64; // 等于二進(jìn)制 1000000
let newValue = oldValue >> 5; // 等于二進(jìn)制 10,即十進(jìn)制 2

同樣,移位后就會(huì)出現(xiàn)空位。不過,右移后空位會(huì)出現(xiàn)在左側(cè),且在符號(hào)位之后(見圖 3-3)。 ECMAScript 會(huì)用符號(hào)位的值來(lái)填充這些空位,以得到完整的數(shù)值。

JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的

無(wú)符號(hào)右移 >>>

無(wú)符號(hào)右移用 3 個(gè)大于號(hào)表示(>>>),會(huì)將數(shù)值的所有 32 位都向右移。對(duì)于正數(shù),無(wú)符號(hào)右移與 有符號(hào)右移結(jié)果相同。仍然以前面有符號(hào)右移的例子為例,64 向右移動(dòng) 5 位,會(huì)變成 2:

let oldValue = 64; // 等于二進(jìn)制 1000000 
let newValue = oldValue >>> 5; // 等于二進(jìn)制 10,即十進(jìn)制 2

對(duì)于負(fù)數(shù),有時(shí)候差異會(huì)非常大。與有符號(hào)右移不同,無(wú)符號(hào)右移會(huì)給空位補(bǔ) 0,而不管符號(hào)位是 什么。對(duì)正數(shù)來(lái)說,這跟有符號(hào)右移效果相同。但對(duì)負(fù)數(shù)來(lái)說,結(jié)果就差太多了。無(wú)符號(hào)右移操作符將負(fù)數(shù)的二進(jìn)制表示當(dāng)成正數(shù)的二進(jìn)制表示來(lái)處理。因?yàn)樨?fù)數(shù)是其絕對(duì)值的二補(bǔ)數(shù),所以右移之后結(jié)果變 得非常之大,如下面的例子所示:

let oldValue = -64; // 等于二進(jìn)制 11111111111111111111111111000000
let newValue = oldValue >>> 5; // 等于十進(jìn)制 134217726

在對(duì)-64 無(wú)符號(hào)右移 5 位后,結(jié)果是 134 217 726。這是因?yàn)?64 的二進(jìn)制表示是 1111111111111111111 1111111000000,無(wú)符號(hào)右移卻將它當(dāng)成正值,也就是 4 294 967 232。把這個(gè)值右移 5 位后,結(jié)果是 00000111111111111111111111111110,即 134 217 726。

實(shí)戰(zhàn)中的妙用

1.判斷奇偶數(shù)

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

2. 使用^來(lái)完成值的交換

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

3. 使用~進(jìn)行判斷

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

4. 使用&、>>|來(lái)完成rgb值和16進(jìn)制顏色值之間的轉(zhuǎn)換

/**
 * 16進(jìn)制顏色值轉(zhuǎn)RGB
 * @param  {String} hex 16進(jìn)制顏色字符串
 * @return {String}     RGB顏色字符串
 */
  function hexToRGB(hex) {
    var hexx = hex.replace('#', '0x')
    var r = hexx >> 16
    var g = hexx >> 8 & 0xff
    var b = hexx & 0xff
    return `rgb(${r}, ${g}, $)`
}

/**
 * RGB顏色轉(zhuǎn)16進(jìn)制顏色
 * @param  {String} rgb RGB進(jìn)制顏色字符串
 * @return {String}     16進(jìn)制顏色字符串
 */
function RGBToHex(rgb) {
    var rgbArr = rgb.split(/[^\d]+/)
    var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3]
    return '#'+ color.toString(16)
}
// -------------------------------------------------
hexToRGB('#ffffff')               // 'rgb(255,255,255)'
RGBToHex('rgb(255,255,255)')      // '#ffffff'

5. 使用|、~、>>、<<、>>>來(lái)取整

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

上述內(nèi)容就是JavaScript中的7種位運(yùn)算符是如何在實(shí)戰(zhàn)中使用的,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI