你可能不知道的JavaScript位運算符詳解
概覽
本文詳細剖析JavaScript的位運算符,其涉及的計算機原理和操作效果。
然后從實戰(zhàn)的角度出發(fā),羅列相關(guān)的應(yīng)用場景。
位操作符概覽
運算符 | 描述 | 示例 |
---|---|---|
按位與(AND) | 兩個操作數(shù)對應(yīng)的比特位都是1時,結(jié)果才為1,否則為0 | 1011 & 0111 = 0011 |
按位或(OR) | 兩個操作數(shù)對應(yīng)的比特位至少有一個1時,結(jié)果為1,否則為0 | 1011 | 0111 = 1111 |
按位異或(XOR) | 兩個操作數(shù)對應(yīng)的比特位有且只有一個1時,結(jié)果為1,否則為0 | 1011 ^ 0111 = 1100 |
按位非(NOT) | 逐個反轉(zhuǎn)操作數(shù)的比特位,即0變成1,1變成0 | ~1011 = 0100 |
左移 | 通過從右推入零向左位移,并使最左邊的位脫落。 | 1011 << 1 = 10110 |
有符號右移 | 通過從左推入最左位的拷貝來向右位移,并使最右邊的位脫落。 | 01011 >> 1 = 00101 |
無符號右移 | 通過從左推入零來向右位移,并使最右邊的位脫落。 | 01011 >>> 1 = 00101 |
位操作支持多少位?
js只支持32位二進制數(shù)的位操作,也即能處理的最大十進制數(shù)字是 4294967295
。
parseInt('11111111111111111111111111111111', 2); // 4294967295
驗證下超過32位二進制數(shù)的位操作:
// 33位二進制數(shù),得到十進制數(shù)字 8589934591 parseInt('111111111111111111111111111111111', 2); // 8589934591 // 對數(shù)字進行無符號位右移 8589934591 >>> 0; // 4294967295 4294967295 >>> 0; // 4294967295
可以看出,數(shù)字 8589934591
和 4294967295
進行 無符號位右移0位
操作,得到的結(jié)果是一樣的。
產(chǎn)生這樣結(jié)果的原因,是js的位操作實現(xiàn),只支持32位
。
注意:
ECMAScript
中的所有數(shù)值都以IEEE754
64位格式存儲,只是在位操作的時候 ,需要轉(zhuǎn)換成32位進行操作。
負數(shù)的無符號右移
-2 >>> 1
為什么輸出2147483647
?
-2
在運算中,是用補碼表示,即1 1111111111111111111111111111110
。
其中,第1位是符號位。 符號位1
代表當前數(shù)字是負數(shù)。
將-2
無符號右移1位,則最右邊的0
脫落,剩下31位1111111111111111111111111111111
,接著,在左側(cè)補0
,得到01111111111111111111111111111111
。
01111111111111111111111111111111
代表十進制數(shù)2147483647
。
狀態(tài)控制
場景:
以下使用React
+TypeScript
,實現(xiàn)游戲狀態(tài)機的狀態(tài)流轉(zhuǎn),根據(jù)狀態(tài)渲染對應(yīng)的操作按鈕。
// 游戲狀態(tài)定義 export enum GAME_STATE{ INIT = 1 << 0, // 二進制表示:00001 JOIN = 1 << 1, // 二進制表示:00010 PREPARE = 1 << 2, // 二進制表示:00100 PLAY = 1 << 3, // 二進制表示:01000 }
// 根據(jù)狀態(tài)渲染按鈕 function RenderButton({state, changeState}){ if((state & GAME_STATE.PLAY) === GAME_STATE.PLAY){ return null; } if((state & GAME_STATE.INIT) === GAME_STATE.INIT){ return <button onClick={() => changeState(GAME_STATE.JOIN)} >加入游戲</button> } if((state & GAME_STATE.JOIN) === GAME_STATE.JOIN){ return <button onClick={() => changeState(GAME_STATE.PREPARE)} >準備游戲</button> } if((state & GAME_STATE.PREPARE) === GAME_STATE.PREPARE){ return <button onClick={() => changeState(GAME_STATE.PLAY)} >開始游戲</button> } return null; } // 渲染游戲頁面 function Page(){ const state = useRef(GAME_STATE.INIT); const changeState = useCallback((newState) => { state.current = newState; }, [state]); return (<div> // ....other code <RenderButton state={state.current} changeState={changeState} /> </div>); }
權(quán)限控制
設(shè)計一個權(quán)限控制,用于不同角色對網(wǎng)站文章的權(quán)限分配。
export enum ARTICLE_RULE{ VIEW = 1 << 0, // 查看文章 EDIT = 1 << 1, // 編輯文章 PUBLISH = 1 << 2, // 發(fā)布文章 DELETE = 1 << 3, // 刪除文章 } export enum ROLE{ GUEST = ARTICLE_RULE.VIEW, // 訪客 ADMIN = ARTICLE_RULE.VIEW | ARTICLE_RULE.EDIT | ARTICLE_RULE.PUBLISH | ARTICLE_RULE.DELETE, // 超級管理員 OPERATOR = ARTICLE_RULE.VIEW | ARTICLE_RULE.EDIT | ARTICLE_RULE.PUBLISH, // 運營 }
if(user.role === 'admin'){ console.log("user擁有admin權(quán)限"); user.rule = ROLE.ADMIN; // 賦予角色權(quán)限 } if((user.rule & ARTICLE_RULE.DELETE) === ARTICLE_RULE.DELETE){ console.log("user擁有刪除文章權(quán)限"); }
判斷奇偶數(shù)
奇數(shù),最末尾1位,一定是1
。
所以將數(shù)字與1
(二進制表示為:00000000000000000000000000000001
)作位操作&
。
如果等于1
,則是奇數(shù)。
function isOdd(number){ return number & 1 === 1; }
交換兩個變量的值
let a = 1; let b = 2; a = a ^ b; // 這一步,a緩存了 a ^ b 的結(jié)果 b = a ^ b; // 等價為: b = a ^ b ^ b, 其中 b ^ b = 0; 所以 b = a ^ 0 = a a = a ^ b; // 同上
判斷整數(shù)是否相等
function isEqual(number1, number2){ return (number1 ^ number2) === 0; }
判斷是否為負數(shù)
如果是負數(shù),則對數(shù)字進行 無符號右移
位操作,會變成一個新的數(shù)字。
所以,如果是負數(shù),則兩個數(shù)字不相等。
function isMinus(number){ return number !== (number >>> 0); }
正浮點數(shù)取整
function toInt(floatNumber){ return floatNumber >>> 0; }
正負浮點數(shù)取整
function toInt(floatNumber){ return floatNumber | 0; }
function toInt(floatNumber){ return ~~floatNumber; }
function toInt(floatNumber){ return floatNumber >> 0; }
十進制轉(zhuǎn)換成二進制
function dec2bin(dec){ return (dec).toString(2); }
二進制轉(zhuǎn)換成十進制
function bin2dec(bin){ return parseInt(`${bin}`, 2) }
參考
到此這篇關(guān)于JavaScript位運算符的文章就介紹到這了,更多相關(guān)JS位運算符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript下的時間格式處理函數(shù)Date.prototype.format
這篇文章主要介紹了JavaScript下的時間格式處理函數(shù)Date.prototype.format的相關(guān)資料,需要的朋友可以參考下2016-01-01js在數(shù)組中刪除重復(fù)的元素自保留一個(兩種實現(xiàn)思路)
遍歷要刪除的數(shù)組arr, 把元素分別放入另一個數(shù)組tmp中,在判斷該元素在arr中不存在才允許放入tmp中,具體實現(xiàn)如下,需要的朋友可以看看2014-08-08微信小程序?qū)崿F(xiàn)watch監(jiān)聽
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)watch監(jiān)聽,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06滾動條響應(yīng)鼠標滑輪事件實現(xiàn)上下滾動的js代碼
javascript實現(xiàn)滾動條響應(yīng)鼠標滑輪的實現(xiàn)上下滾動,示例代碼如下2014-06-06使用ef6創(chuàng)建oracle數(shù)據(jù)庫的實體模型遇到的問題及解決方案
這篇文章主要介紹了使用ef6創(chuàng)建oracle數(shù)據(jù)庫的實體模型遇到的問題及解決方案,需要的朋友可以參考下2017-11-11