以前在某个项目中,遇到了许多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]
参考文献