1. 程式人生 > 其它 >js中 something >>> 0是什麼意思?

js中 something >>> 0是什麼意思?

今天在看lodash的原始碼中slice這個函式實現的時候發現了裡面有這麼一行程式碼

length = start > end ? 0 : ((end - start) >>> 0)

start >>>= 0

當時就很疑惑,知道 >>是移位,那>>>又是什麼鬼,還有移位0位又有什麼意義呢,帶著強烈的好奇心,我就去探究了一下 >>> 0它到底暗藏什麼玄機。

>> 和 >>>有什麼不一樣

查了MDN原來>>>是無符號右移,>>是有符號移位,

>>有符號移位

該操作符會將第一個運算元向右移動指定的位數。向右被移出的位被丟棄,拷貝最左側的位以填充左側

-9 >> 2

11111111111111111111111111110111 // -9 -> 11111111111111111111111111111101   // -3

>>>無符號移位:

該操作符會將第一個運算元向右移動指定的位數。向右被移出的位被丟棄,左側用0填充。因為符號位變成了 0,所以結果總是非負的。(即便右移 0 個位元,結果也是非負的。)

9 >>> 2

00000000000000000000000000001001   // 9 ->  00000000000000000000000000000010 // 2

根據文件說明即使移動0位也可以將一個負數變成正數,甚至也可以將一個小數變成整數,將未定義的值轉換為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.
原來移位操作符在移位前做了兩種轉換,
第一將不是number型別的資料轉換為number,
第二將number轉換為無符號的32bit資料,也就是Uint32型別。
這些與移位的位數無關,移位0位主要就是用了js的內部特性做了前兩種轉換。

Uint32型別是如何轉換的

1 . 如果不能轉換為Number,那就為0
2 . 如果為非整數,先轉換為整數,參考公式sign(n) ⋅ floor(abs(n))

function ToInteger(x) {

    x = Number(x);

 return x < 0 ? Math.ceil(x) : Math.floor(x);

}

3 . 如果是正數,返回正數,如果是負數,返回負數 + 2的32次方

function modulo(a, b) {

 return a - Math.floor(a/b)*b;

}

function ToUint32(x) {

 return modulo(ToInteger(x), Math.pow(2, 32));

}

總結

x >>> 0本質上就是保證x有意義(為數字型別),且為正整數,在有效的陣列範圍內(0 ~ 0xFFFFFFFF),且在無意義的情況下預設值為0。一個小小的表示式,隱藏著著多重的異常處理。js真是詭異啊。