以前在某個項目中,遇到了許多JS的二進制操做場景,所以總結下JS中的二進制操做方法。javascript
所謂二進制操做,是指操做變量實際存儲的值,好比獲取字符A
的Unicode值,或者將值100填入到8個字節中。java
JS中的位操做與不少語言相似,具體的位運算符以下表所示。數組
運算符 | 用法 | 描述 |
---|---|---|
按位與 | a & b | 對於每個比特位,只有兩個操做數相應的比特位都是1時,結果才爲1,不然爲0。 |
按位或 | a | b | 對於每個比特位,當兩個操做數相應的比特位至少有一個1時,結果爲1,不然爲0。 |
按位異或 | a ^ b | 對於每個比特位,當兩個操做數相應的比特位有且只有一個1時,結果爲1,不然爲0。 |
按位非 | ~ a | 反轉操做數的比特位,即0變成1,1變成0。 |
左移 | a << b | 將 a 的二進制形式向左移 b (< 32) 比特位,右邊用0填充。 |
有符號右移 | a >> b | 將 a 的二進制表示向右移 b (< 32) 位,丟棄被移出的位。 |
無符號右移 | a >>> b | 將 a 的二進制表示向右移 b (< 32) 位,丟棄被移出的位,並使用 0 在左側填充。 |
在介紹具體的方法前,咱們須要先了解下UCS-2和UTF-16編碼。緩存
UCS-2是一個16bit長度的編碼集,它的表示範圍是0到0xFFFF。UTF-16的表示範圍是0到0x10FFFF,它由1個或者2個16bit的編碼單元組成。其中UCS-2是UTF-16的子集,UTF-16編碼在0到0x00FFFF的範圍稱爲BMP(基本多文種平面),BMP與UCS-2的編碼徹底一致。編碼
更詳細的說明能夠參考這裏。prototype
fromCharCode
方法返回指定的UCS-2編碼對應的字符串。它是String
上的靜態方法,不可經過字符串對象直接訪問。code
由於入參是UCS-2編碼值,因此不能多於16bit,即入參值要小於65536。若是入參須要大於65536,可使用 String.fromCodePoint
。對象
String.fromCharCode(65) // A String.fromCharCode(65, 66, 68) // ABD
charCodeAt
返回字符串指定位置的字符的UTF-16編碼。該方法能夠直接從字符串對象進行調用。ip
若是該字符不能使用一個UTF-16編碼單元(16bit)來表示時,該方法只會返回第一個編碼單元。若是須要獲取完整的編碼,可使用 String.prototype.codePointAt
。字符串
"AB".charCodeAt(0) // 65 "AB".charCodeAt(1) // 66
ArrayBuffer
用來表示原始的二進制數據緩存區,可是不可直接對ArrayBuffer
進行操做,須要藉助DataView
或者類型數組對象來對緩存區的內容進行讀寫。
DataView
能夠理解爲數據視窗,經過 DataView
對象能夠對 ArrayBuffer
進行讀寫操做。
const buffer = new ArrayBuffer(4); // 申請2個字節長度的緩存區 const view1 = new DataView(buffer); // view1的範圍是整個緩存區 const view2 = new DataView(buffer, 2, 1) // view2的範圍是從第2個字節開始日後的一個字節 // 向一個16bit的內容中填入一個帶符號的數 // 參數的含義依次爲 輸入內容的位置、輸入的值、是否使用小端方式(默認大端) view1.setInt16(0, 0x0A0B, false); view1.getInt8(0); // 10,即0x0A view1.getInt8(1); // 11,即0x0B view2.setUint8(0, 255); view2.getInt8(0); // 按照有符號數來讀取,結果爲-1
更多的操做方法能夠參考DataView。
類型數組對象有不少種,好比Uint8Array
, Int32Array
等。將ArrayBuffer
轉化爲類型數組後,就能夠像數組同樣來操做緩存區。
const buffer = new ArrayBuffer(8); const arr1 = new Int16Array(buffer); const arr2 = new Uint8Array(buffer); arr1[0] = 256; arr2[6] = 255; console.log(arr1); // [256, 0, 0, 255] console.log(arr2); // [0, 1, 0, 0, 0, 0, 255, 0]
參考文獻