摘要:向右被移出的位被丟棄,左側(cè)用填充。因為符號位變成了,所以結(jié)果總是非負的。即便右移個比特,結(jié)果也是非負的。這些與移位的位數(shù)無關(guān),移位位主要就是用了的內(nèi)部特性做了前兩種轉(zhuǎn)換。一個小小的表達式,隱藏著著多重的異常處理。
今天在看lodash的源碼中slice這個函數(shù)實現(xiàn)的時候發(fā)現(xiàn)了里面有這么一行代碼
length = start > end ? 0 : ((end - start) >>> 0) start >>>= 0
當時就很疑惑,知道 >>是移位,那>>>又是什么鬼,還有移位0位又有什么意義呢,帶著強烈的好奇心,我就去探究了一下 >>> 0它到底暗藏什么玄機。
>> 和 >>>有什么不一樣
查了MDN原來>>>是無符號右移,>>是有符號移位,
>>有符號移位:該操作符會將第一個操作數(shù)向右移動指定的位數(shù)。向右被移出的位被丟棄,拷貝最左側(cè)的位以填充左側(cè)
-9 >> 2 11111111111111111111111111110111 // -9 -> 11111111111111111111111111111101 // -3
>>>無符號移位:該操作符會將第一個操作數(shù)向右移動指定的位數(shù)。向右被移出的位被丟棄,左側(cè)用0填充。因為符號位變成了 0,所以結(jié)果總是非負的。(即便右移 0 個比特,結(jié)果也是非負的。)
9 >>> 2 00000000000000000000000000001001 // 9 -> 00000000000000000000000000000010 // 2
根據(jù)文檔說明即使移動0位也可以將一個負數(shù)變成正數(shù),甚至也可以將一個小數(shù)變成整數(shù),將未定義的值轉(zhuǎn)換為0,那到底移動0位是什么意思。
移位0有什么意義
查過一些資料,其中stackoverflow里面有一個高票回答,里面有這么一句話
It doesn"t just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.
原來移位操作符在移位前做了兩種轉(zhuǎn)換,第一將不是number類型的數(shù)據(jù)轉(zhuǎn)換為number,第二將number轉(zhuǎn)換為無符號的32bit數(shù)據(jù),也就是Uint32類型。這些與移位的位數(shù)無關(guān),移位0位主要就是用了js的內(nèi)部特性做了前兩種轉(zhuǎn)換。
Uint32類型是如何轉(zhuǎn)換的
1 . 如果不能轉(zhuǎn)換為Number,那就為0
2 . 如果為非整數(shù),先轉(zhuǎn)換為整數(shù),參考公式sign(n) ? floor(abs(n))
function ToInteger(x) { x = Number(x); return x < 0 ? Math.ceil(x) : Math.floor(x); }
3 . 如果是正數(shù),返回正數(shù),如果是負數(shù),返回負數(shù) + 2的32次方
function modulo(a, b) { return a - Math.floor(a/b)*b; } function ToUint32(x) { return modulo(ToInteger(x), Math.pow(2, 32)); }
參考文章 Integers and shift operators in JavaScript
總結(jié)
x >>> 0本質(zhì)上就是保證x有意義(為數(shù)字類型),且為正整數(shù),在有效的數(shù)組范圍內(nèi)(0 ~ 0xFFFFFFFF),且在無意義的情況下缺省值為0。一個小小的表達式,隱藏著著多重的異常處理。js真是詭異啊。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/94623.html
JavaScript 的 switch 有四樣寫法,你都知道哪些? JavaScript 的 switch 語句只有一種寫法。其他的寫法,if 分支寫法可以算一種,switch 分支寫法可以算第二種,第三種是使用策略模式,如果要把條件運算符也算上的話,嗯,剛好四種?! witch一般寫法 switch 的寫法一般來說是 switch 變量或表達式,case 常量,比如:一個百分制成績,...
我們現(xiàn)在要講述的是當解析器遇到一個文本節(jié)點時會如何為文本節(jié)點創(chuàng)建元素描述對象,那又該作何處理?! arseHTML(template,{ chars:function(){ //... }, //... }) chars源碼: chars:functionchars(text){ if(!currentParent){ { if(text===templ...
let和const let和const兩者并不存在變量提升 這里要說明的是變量一定要在聲明后使用,否則報錯?! ara=[]; for(vari=0;i<10;i++){ a[i]=function(){ console.log(i); }; } a[6]();//10 變量i是var聲明的,我們要知道這里在全局范圍內(nèi)都有效。我們要知道在每一次循環(huán)中,新的...
直接進入核心現(xiàn)在說說baseCompile核心代碼: //`createCompilerCreator`allowscreatingcompilersthatusealternative //parser/optimizer/codegen,e.gtheSSRoptimizingcompiler. //Herewejustexportadefaultcompilerusingthede...
前言 在JS是用來時間復(fù)雜度和空間復(fù)雜度,時間復(fù)雜度和空間復(fù)雜度是衡量一個算法是否優(yōu)秀的標準,現(xiàn)在我們就來說手時間復(fù)雜度和空間復(fù)雜度?! r間復(fù)雜度和空間復(fù)雜度是衡量一個算法是否優(yōu)秀的標準,通常我們比較兩個算法時會用到以下兩種方法: 預(yù)先估算:首先做出算法設(shè)計,在去估算這個算法所需的時間復(fù)雜度和空間復(fù)雜度,兩者進行比較,擇優(yōu)?! ∈潞蠼y(tǒng)計:寫一個可執(zhí)行程序/腳本用來表達兩個算法,交給計算機...
閱讀 1684·2019-08-30 15:54
閱讀 2447·2019-08-30 15:52
閱讀 2168·2019-08-29 15:33
閱讀 3093·2019-08-28 17:56
閱讀 3294·2019-08-26 13:54
閱讀 1728·2019-08-26 12:16
閱讀 2507·2019-08-26 11:51
閱讀 1717·2019-08-26 10:26