js中表達式 >>> 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));
}

參考文章 Integers and shift operators in JavaScript

  • 總結

x >>> 0本質上就是保證x有意義(為数字範例),且為正整數,在有用的數組範圍內(0 ~ 0xFFFFFFFF),且在無意義的情況下缺省值為0。一個小小的表達式,隱蔽着着多重的非常處置懲罰。js真是詭異啊。

    原文作者:dongzhe3917875
    原文地址: https://segmentfault.com/a/1190000014613703
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞