JS的二进制操作
栏目: JavaScript · 发布时间: 7年前
内容简介:之前在某个项目中,遇到了许多JS的二进制操作场景,因此总结下JS中的二进制操作方法。所谓二进制操作,是指操作变量实际存储的值,比如获取字符JS中的位操作与很多语言类似,具体的位运算符如下表所示。
之前在某个项目中,遇到了许多JS的二进制操作场景,因此总结下JS中的二进制操作方法。
所谓二进制操作,是指操作变量实际存储的值,比如获取字符 A
的Unicode值,或者将值100填入到8个字节中。
1. 位操作符
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 在左侧填充。 |
2. 字符和Unicode编码
在介绍具体的方法前,我们需要先了解下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的编码完全一致。
更详细的说明可以 参考这里 。
2.1 String.fromCharCode
fromCharCode
方法返回指定的UCS-2编码对应的字符串。它是 String
上的静态方法,不可通过字符串对象直接访问。
因为入参是UCS-2编码值,所以不能多于16bit,即入参值要小于65536。如果入参需要大于65536,可以使用 String.fromCodePoint
。
String.fromCharCode(65) // A String.fromCharCode(65, 66, 68) // ABD
2.2 String.prototype.charCodeAt
charCodeAt
返回字符串指定位置的字符的UTF-16编码。该方法可以直接从字符串对象进行调用。
如果该字符不能使用一个UTF-16编码单元(16bit)来表示时,该方法只会返回第一个编码单元。如果需要获取完整的编码,可以使用 String.prototype.codePointAt
。
"AB".charCodeAt(0) // 65 "AB".charCodeAt(1) // 66
3. ArrayBuffer
ArrayBuffer
用来表示原始的二进制数据缓存区,但是不可直接对 ArrayBuffer
进行操作,需要借助 DataView
或者类型数组对象来对缓存区的内容进行读写。
3.1 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 。
3.2 类型数组对象
类型数组对象有很多种,比如 Uint8Array
, Int32Array
等。将 ArrayBuffer
转化为类型数组后,就可以像数组一样来操作缓存区。
const buffer = new ArrayBuffer(8); const arr1 = new Int16Array(buffer); const arr2 = new Uint8Array(buffer); arr1[0] = 256; arr2[7] = 255; console.log(arr1); // [256, 0, 0, 255] console.log(arr2); // [0, 1, 0, 0, 0, 0, 255, 0]
参考文献
- 按位操作符 - JavaScript | MDN
- [Unicode字符平面映射](之前在某个项目中,遇到了许多JS的二进制操作场景,因此总结下JS中的二进制操作方法。
所谓二进制操作,是指操作变量实际存储的值,比如获取字符 A
的Unicode值,或者将值100填入到8个字节中。
1. 位操作符
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 在左侧填充。 |
2. 字符和Unicode编码
在介绍具体的方法前,我们需要先了解下UCS-2和UTF-16编码。
UCS-2是一个16bit长度的编码集,它的表示范围是0到0xFFFF。UTF-16的表示范围是0到0x10FFFF,它由1个或者2个16bit的编码单元组成。UCS-2是UTF-16的子集,当字符的编码范围在0x00FFFF。
更详细的说明可以 参考这里 。
2.1 String.fromCharCode
fromCharCode
方法返回指定UCS-2编码对应的字符串。它是 String
上的静态方法,不可通过字符串对象直接访问。
所以 fromCharCode
的入参值要小于65536。否则需要使用 String.fromCodePoint
代替。
String.fromCharCode(65) // A String.fromCharCode(65, 66, 68) // ABD
2.2 String.prototype.charCodeAt
charCodeAt
返回字符串指定位置的字符的UTF-16编码。该方法可以直接从字符串对象进行调用。
如果该字符不能使用一个UTF-16编码单元(16bit)来表示时,该方法只会返回第一个编码单元。如果需要获取完整的编码,需要使用 String.prototype.codePointAt
代替。
"AB".charCodeAt(0) // 65 "AB".charCodeAt(1) // 66
PS:
3. ArrayBuffer
ArrayBuffer
用来表示原始的二进制数据缓存区,类似于申请一块内存空间,但是不可直接对缓存区进行操作,需要借助 DataView
或者类型数组对象来对缓存区的内容进行读写。
3.1 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 。
3.2 类型数组对象
类型数组对象有很多种,比如 Uint8Array
, Int32Array
等。将 ArrayBuffer
转化为类型数组后,就可以像数组一样来操作缓存区。
const buffer = new ArrayBuffer(8); const arr1 = new Int16Array(buffer); const arr2 = new Uint8Array(buffer); arr1[0] = 256; arr2[7] = 255; console.log(arr1); // [256, 0, 0, 255] console.log(arr2); // [0, 1, 0, 0, 0, 0, 255, 0]
参考文献
以上所述就是小编给大家介绍的《JS的二进制操作》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Code Reading
Diomidis Spinellis / Addison-Wesley Professional / 2003-06-06 / USD 64.99
This book is a unique and essential reference that focuses upon the reading and comprehension of existing software code. While code reading is an important task faced by the vast majority of students,......一起来看看 《Code Reading》 这本书的介绍吧!