JavaScript中7種位運(yùn)算符在實(shí)戰(zhàn)的妙用
本篇文章帶大家了解一下JavaScript中的7種位運(yùn)算符,看看如何妙用這7種位運(yùn)算符,希望對(duì)大家有所幫助!
位運(yùn)算符
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, 或更精簡的 10010。后者是用到的 5 個(gè)有效位,決定了實(shí)際的值(如下圖所示)。

按位非 ~
按位非操作符用波浪符(~)表示,它的作用是返回?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)的與操作。

按位與操作在兩個(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ì)算過程:

如上圖所示,25 和 3 的二進(jìn)制表示中,只有第 0 位上的兩個(gè)數(shù)都是 1。于是結(jié)果數(shù)值的所有其他位都 會(huì)以 0 填充,因此結(jié)果就是 1。
按位或 |
按位或操作符用管道符(|)表示,同樣有兩個(gè)操作數(shù)。按位或遵循如下真值表:

按位或操作在至少一位是 1 時(shí)返回 1,兩位都是 0 時(shí)返回 0。 仍然用按位與的示例,如果對(duì) 25 和 3 執(zhí)行按位或,代碼如下所示:
let result = 25 | 3; console.log(result); // 27
可見 25 和 3 的按位或操作的結(jié)果是 27:

在參與計(jì)算的兩個(gè)數(shù)中,有 4 位都是 1,因此它們直接對(duì)應(yīng)到結(jié)果上。二進(jìn)制碼 11011 等于 27。
按位異或 ^
按位異或用脫字符(^)表示,同樣有兩個(gè)操作數(shù)。下面是按位異或的真值表:

按位異或與按位或的區(qū)別是,它只在一位上是 1 的時(shí)候返回 1(兩位都是 1 或 0,則返回 0)。 對(duì)數(shù)值 25 和 3 執(zhí)行按位異或操作:
let result = 25 ^ 3; console.log(result); // 26
可見,25 和 3 的按位異或操作結(jié)果為 26,如下所示:

兩個(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ù)值(見下圖)。

注意,左移會(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)位的值來填充這些空位,以得到完整的數(shù)值。

無符號(hào)右移 >>>
無符號(hào)右移用 3 個(gè)大于號(hào)表示(>>>),會(huì)將數(shù)值的所有 32 位都向右移。對(duì)于正數(shù),無符號(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)右移不同,無符號(hào)右移會(huì)給空位補(bǔ) 0,而不管符號(hào)位是 什么。對(duì)正數(shù)來說,這跟有符號(hào)右移效果相同。但對(duì)負(fù)數(shù)來說,結(jié)果就差太多了。無符號(hào)右移操作符將負(fù)數(shù)的二進(jìn)制表示當(dāng)成正數(shù)的二進(jìn)制表示來處理。因?yàn)樨?fù)數(shù)是其絕對(duì)值的二補(bǔ)數(shù),所以右移之后結(jié)果變 得非常之大,如下面的例子所示:
let oldValue = -64; // 等于二進(jìn)制 11111111111111111111111111000000 let newValue = oldValue >>> 5; // 等于十進(jìn)制 134217726
在對(duì)-64 無符號(hào)右移 5 位后,結(jié)果是 134 217 726。這是因?yàn)?64 的二進(jìn)制表示是 1111111111111111111 1111111000000,無符號(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. 使用^來完成值的交換
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. 使用&、>>、|來完成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('Id', '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 '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 // >>>不可對(duì)負(fù)數(shù)取整 console.log(3.1415 >>> 0) // 3
【相關(guān)推薦:】
以上就是聊聊JavaScript中的7種位運(yùn)算符,看看在實(shí)戰(zhàn)中如何妙用?的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
參考地址:http://www.php.cn//js-tutorial-487096.html
到此這篇關(guān)于JavaScript中7種位運(yùn)算符在實(shí)戰(zhàn)的妙用的文章就介紹到這了,更多相關(guān)JS位運(yùn)算符實(shí)戰(zhàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript中的數(shù)據(jù)類型介紹
- javaScript中一些常見的數(shù)據(jù)類型檢查校驗(yàn)
- javascript基本數(shù)據(jù)類型和對(duì)象類型歸檔問題解析
- javascript基礎(chǔ)數(shù)據(jù)類型轉(zhuǎn)換教程示例
- javascript數(shù)據(jù)類型基礎(chǔ)示例教程
- JavaScript數(shù)據(jù)類型轉(zhuǎn)換
- javascript中instanceof運(yùn)算符的用法詳解
- 你可能不知道的JavaScript位運(yùn)算符詳解
- JavaScript詳細(xì)分析數(shù)據(jù)類型和運(yùn)算符
相關(guān)文章
Nuxt.js中PC與移動(dòng)端間自動(dòng)識(shí)別跳轉(zhuǎn)
本文主要介紹了Nuxt.js中PC與移動(dòng)端間自動(dòng)識(shí)別跳轉(zhuǎn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
JavaScript實(shí)現(xiàn)獲取本機(jī)IP地址
這篇文章主要介紹了JavaScript實(shí)現(xiàn)獲取本機(jī)IP地址方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
JavaScript表格隔行變色和Tab標(biāo)簽頁特效示例【附j(luò)Query版】
這篇文章主要介紹了JavaScript表格隔行變色和Tab標(biāo)簽頁特效,結(jié)合實(shí)例形式分析了javascript元素遍歷、事件響應(yīng)相關(guān)操作技巧,并附帶jQuery對(duì)應(yīng)實(shí)現(xiàn)代碼供大家參考,需要的朋友可以參考下2019-07-07
解讀CocosCreator源碼之引擎啟動(dòng)與主循環(huán)
這篇文章主要介紹了CocosCreator源碼解讀之引擎啟動(dòng)與主循環(huán),對(duì)CocosCreator感興趣的同學(xué),可以研究參考一下2021-04-04
最精簡的JavaScript實(shí)現(xiàn)鼠標(biāo)拖動(dòng)效果的方法
這篇文章主要介紹了最精簡的JavaScript實(shí)現(xiàn)鼠標(biāo)拖動(dòng)效果的方法,可實(shí)現(xiàn)javascript控制鼠標(biāo)拖動(dòng)div層效果的方法,需要的朋友可以參考下2015-05-05
js之切換全屏和退出全屏實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了js之切換全屏和退出全屏實(shí)現(xiàn)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
關(guān)于字符串和對(duì)象互轉(zhuǎn)以及JSON.parse()的坑
這篇文章主要介紹了關(guān)于字符串和對(duì)象互轉(zhuǎn)以及JSON.parse()的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

