浅析JavaScript类型化数组TypedArray理解、为什么使用TypedArray、类型数组与普通数组的区别及其常见应用(处理二进制数据类型)

  Javascript 中的数组是个强大的家伙:你可以创建的时候不规定长度,而是动态的去改变长度。你可以把他当成普通的数组去读取,也可以当他是堆栈来使用。你可以改变数组中每个元素的值甚至是类型。其实它是一个对象,比如我们可以这样去创建数组:var array = new Array(10); 

  Javascript 的数组的强大以及全能,给我们带来了便捷性。但一般而言:全能的东西能在各种环境下使用,但却不一定适用于各种环境。而 TypedArray 正是为了解决Javascript 中数组“干太多事”而出现的。

一、什么是类型化数组

  在定制 html5 版本中,TypedArray是一种通用的固定长度缓冲区类型,允许读取缓冲区中的二进制数据。其在WEBGL规范中被引入用于解决Javascript处理二进制数据的问题。类型化数组也是数组,只不过其元素被设置为特定类型的值。

  类型化数组的核心就是一个名为 ArrayBuffer 的类型。每个ArrayBuffer对象表示的只是内存中指定的字节数,但不会指定这些字节用于保存什么类型的数据。通过ArrayBuffer能做的,就是为了将来使用而分配一定数量的字节。

// 创建一个8-byte的ArrayBuffer
var b = new ArrayBuffer(8);

// 创建一个b的引用,类型是Int32,起始位置在0,结束位置为缓冲区尾部
var v1 = new Int32Array(b);

// 创建一个b的引用,类型是Uint8,起始位置在2,结束位置为缓冲区尾部
var v2 = new Uint8Array(b, 2);

// 创建一个b的引用,类型是Int16,起始位置在2,总长度为2
var v3 = new Int16Array(b, 2, 2);

1、类型数组:描述的是二进制缓存区一个类似数组的视图

浅析JavaScript类型化数组TypedArray理解、为什么使用TypedArray、类型数组与普通数组的区别及其常见应用(处理二进制数据类型)

2、构造函数:上面我们通过ArrayBuffer来创建TypedArray,而实际上,TypedArray提供了3个构造函数来创建他的实例。

TypedArray(unsigned long length)   
// 创建一个新的TypedArray,length是其固定长度。

TypedArray(TypedArray array)
TypedArray(type[] array)
// 创建一个新的TypedArray,其每个元素根据array进行初始化,元素进行了相应的类型转换。

TypedArray(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long length)
// 创建一个新的TypedArray,使其作为buffer的一个引用,byteOffset为其起始的偏移量,length为其长度。

二、为什么要用TypedArray

  我们知道Javascript中数字是64位浮点数。则对于一个二进制图片(图片每个像素点是以8位无符号整数存储的),如果要将其数据在Javascript数组中使用,相当于使用了图片8倍的内存来存储一个图片的数据,这显然是不科学的。而TypedArray能帮助我们只使用原来1/8的内存来存储图片数据。

  或者对于WebSocket,如果用base64进行传输也是一个花费较高的方式,转而使用二进制传送可能是更好的方式。

  当然,TypedArray还有更多好处,比如具有更好的性能,下面我们进行一些小测试来验证这一点。

1、顺序读取速读

2、随机读取

3、顺序写入

4、复制操作

  可以看到性能均比 Array 要好。详见这篇文章:https://www.jb51.net/html5/68844.html

三、TypedArray和数组的区别

浅析JavaScript类型化数组TypedArray理解、为什么使用TypedArray、类型数组与普通数组的区别及其常见应用(处理二进制数据类型)

四、实际应用

  传统意义上服务通过AJAX只能返回文本数据,responseType默认是一个text,但是在xhr中,可以设定为一个二进制数据,只需要将responseType设置成arraybuffer

var xhr=new XMLHttpRequest();
xhr.open("GET","/myfile.png",true);
xhr.responseType="arraybuffer";
 
xhr.onload=function (oEvent) {
    var arrayBuffer=xhr.response;
    if (arrayBuffer){
        var byteArray=new Uint8Array(arrayBuffer)
        for (var i=0;i<byteArray.byteLength;i++){
            //对数组中每个元素进行操作
        }
    }
}
xhr.send(null)

  其他应用平时确实用的不多,以后遇到可以考虑看看。