搜索
写经验 领红包
 > 设计

js操作二进制数据(js中二进制数怎么表示)

导语:JS操作内存?二进制数组了解一下

js操作二进制数据(js中二进制数怎么表示)

二进制数组的由来

主要是为了提高浏览器与显卡之间的通信效率,由二进制数据代替传统的文本。

二进制数组主要有三个对象:

ArrayBufferTypedArrayDataView

ArrayBuffer对象

ArrayBuffer是一个构造函数,参数是一个数字,代表索取多少个字节的内存。例如:

var buffer = new ArrayBuffer(12);

代表生成12个字节的内存区域。

注意:ArrayBuffer对象本身并不能直接对生成的内存区域进行读写(除了slice方法),需要借助视图TypedArray和DataView来对其进行读写。

三个方法:

实例方法byteLength,返回生成内存的字节大小实例方法slice,这个方法和数组类似,就是生成一段新的内存,并填充拷贝的内容静态方法isView,是否是视图

demo1

TypedArray的用法

这种类型的视图总共有9种构造函数:

Int8Array 8位 有符号 一个字节 整数Uint8Array 8位 无符号 一个字节 整数Uint8ClampedArray 8位 无符号 一个字节 整数Int16Array 16位 有符号 两个字节 整数Uint16Array 16位 无符号 两个字节 整数Int32Array 32位 有符号 四个字节 整数Uint32Array 32位 无符号 四个字节 整数Float32Array 32位 四个字节 浮点数Float64Array 64位 八个字节 浮点数

用法1:

new TypedArray(buf, start, length)

buf ArrayBuffer对象start开始的位置,默认是0length 字节的长度 相对于这种数据类型的长度

用法2:

new TypedArray(length)

直接传入一个长度,生成一段内存区域

用法3:

new TypedArray(typedArray对象)

demo2

demo2中x和y视图并没有共享内存,如果想共享视图可以这样(传入实例的buffer属性):

demo3

用法4:

new TypedArray(普通的数组)

demo4

demo4中操作typedArray不会使aa发生变化,说明它们没有共用同一段内存。

TypedArray的数值

二进制数组采用小端字节序,数组前面的元素的位相对较低,越往后越高,比如demo5中32这个元素就没有后面0的元素位高,转化成16进制应该是0x0000000000000020,如果采用16位或者32位视图,再对应将其划分。

demo5

小端字节序:低位在前,高位在后;

大端字节序:高位在前,低位在后;

TypedArray的数值溢出

什么是溢出呢?看下图:

demo6

我们创建了一个Uint8Array视图,它每一个元素的最大值是255(8位),最小值是0,当给定的数值不在这个区间内时,就会发生溢出!从demo6中我们给第一个元素赋值5000,但显示的却是136,这种现象就叫做溢出。

那么溢出的规则是什么?经过我的摸索得出了几条规律!

无符号(先利用Uint8Array说明)

Uint8Array最大值255(max),最小值0(min),区间长度256(L),给其一个元素赋值m,最终显示的值是n(例子见demo7)

//无符号最小值都是0if(m >= min){ //正向溢出 n = m%L } if (m < min) { //负向溢出,m是负数 n = L + m%L}

demo7

有符合(先利用Int8Array说明)

Int8Array最大值127(max),最小值-128(min),区间长度256(L),给其一个元素赋值m,最终显示的值是n(例子见demo8)

余数y = m%L//正向溢出(m是正数)if (y <= max) { n = y} if (y > max) { n = y - L}//负向溢出(此时y,min都是负数)if (y >= min) { n = y}if (y < min) { n = L + y}

demo8

DataView对象

DataView对象和TypedArray对象最大的区别是可以自定义大端字节序还是小端字节序!

用法:

var buf = new ArrayBuffer(n);var dv = new DataView(buf, 字节起始位置, 长度);//查看demo6

demo9

8个get方法:

getInt8:读取1个字节,返回一个8位整数。getUint8:读取1个字节,返回一个无符号的8位整数。getInt16:读取2个字节,返回一个16位整数。getUint16:读取2个字节,返回一个无符号的16位整数。getInt32:读取4个字节,返回一个32位整数。getUint32:读取4个字节,返回一个无符号的32位整数。getFloat32:读取4个字节,返回一个32位浮点数。getFloat64:读取8个字节,返回一个64位浮点数。
//使用样例dv.getXX(第几个字节,大端字节序(false)/小端字节序(true))

8个set方法:

setInt8:写入1个字节的8位整数。setUint8:写入1个字节的8位无符号整数。setInt16:写入2个字节的16位整数。setUint16:写入2个字节的16位无符号整数。setInt32:写入4个字节的32位整数。setUint32:写入4个字节的32位无符号整数。setFloat32:写入4个字节的32位浮点数。setFloat64:写入8个字节的64位浮点数。
//使用样例dv.setXX(第几个字节,数据, 大端字节序(false)/小端字节序(true))

总结

其实二进制数组在平时工作中并不常用,甚至不常见,不过还是有必要了解一下的!因为它是buffer的基础,所以在研究buffer之前先了解一下!因为根据我的测试,自己摸索出了一个通用的规则,帮助大家理解,大家也可以帮我验证,大家有想法的也可以留言给我补充!

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!

本文内容由小涵整理编辑!