JavaScript中你所不知道的数组ArrayBuffer

JavaScript中你所不知道的数组ArrayBufferJavaScript中你所不知道的数组ArrayBuffer
前段时间一直在研究 Web Audio API 以及语音通讯相关的知识,内容侧重于音频流在 AudioContext 各个节点之间的流动状况,而如今要摸清楚音频到流底是个什么样的数据格式,因此对 ArrayBuffer 的研究就显得格外重要了。javascript

1、Array 在内存中的堆栈模型html

1. Array 的获取前端

Javascript 中如何产生 Array:html5

[element0, element1, ..., elementN]
new Array(element0, element1, ..., elementN)
new Array(arrayLength)

直接定义,或者经过构造函数建立一个 Array,固然也可使用其余的手段:java

"array".split("");
"array".match(/a|r/g);

等等,方式有不少。可是 Array 内部是个什么样的结构,恐怕不少人还不是很清楚。linux

2. 堆栈模型ios

在数组中咱们能够放不少不一样数据类型的数据,如:web

var arr = [21, "李靖", new Date(), function(){}, , null];

上面这个数组中一次放入了 数字、字符串、对象、函数、undefined 和 null,对于上面的数据接口咱们能够具象的描述下:chrome

栈
+---------+                  堆
|   21    |         +-------------------+
+---------+         |                   |
|  "李靖" |         |                   |
+---------+         |  +--------+       |
| [refer] |----------->| Object |       |
+---------+         |  +--------+       |
| [refer] |----------------->+--------+ |
+---------+         |        |function| |
|undefined|         |        +--------+ |
+---------+         |                   |
|   null  |         +-------------------+
+---------+         Created By Barret Lee

JavaScript 的数据类型分为两种,一种是值类型,一种是引用类型,常见的引用类型有 Object 和 Array,数组的储存模型中,若是是诸如 Number、String 之类的值类型数据会被直接压入栈中,而引用类型只会压入对该值的一个索引,用 C 语言的概念来解释就是只保存了数据的指针,这些数据是储存在堆中的某块区间中。栈堆并非独立的,栈也能够在堆中存放。数组

好了,对 Array 的说明就到这里,下面具体说说 ArrayBuffer 的相关知识。

2、ArrayBuffer

web 是个啥玩意儿,web 要讨论的最基本问题是什么?我以为有两点,一个是数据,一个是数据传输,至于数据的展现,纷繁复杂,这个应该是 web 上层的东西。而本文要讨论的 ArrayBuffer 就是最基础的数据类型,甚至不能称之为数据类型,它是一个数据容易,须要经过其余方式来读写。

官方点的定义:

The ArrayBuffer is a data type that is used to represent a generic, fixed-length binary data buffer. You can't directly manipulate the contents of an ArrayBuffer; instead, you create an ArrayBufferView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.
表示二进制数据的原始缓冲区,该缓冲区用于存储各类类型化数组的数据。 没法直接读取或写入 ArrayBuffer,但可根据须要将其传递到类型化数组或 DataView 对象 来解释原始缓冲区。

他是一个二进制数据的原始缓冲区,虽然 JavaScript 是弱类型语言,可是他自己是对数据的类型和大小都有限制的,咱们须要经过某种数据结构将缓冲区的内容有序的读取出来(写进去)。

1. 原始缓冲区的建立

经过 ArrayBuffer 这个构造函数能够建立一个原始缓冲区:

var buffer  = new ArrayBuffer(30);

从 chrome 控制台能够看到:

[![arrayBuffer]({{ site.repo }}/images/blog-article-images/blog/audio/arraybuffer.jpg)]({{ site.repo }}/images/blog-article-images/blog/audio/arraybuffer.jpg)

buffer 实例拥有一个 byteLength 的属性,用于获取 buffer 的 size,一个只有 IE11+ 以及 ios6+ 支持的 slice 方法,用于对 buffer 长度进行截取操做。

ArrayBuffer slice(
    unsigned long begin
    unsigned long end Optional
);

能够测试这个 DEMO:

var buffer = new ArrayBuffer(12);
var x = new Int32Array(buffer);
x[1] = 1234;
var slice = buffer.slice(4);
var y = new Int32Array(slice);
console.log(x[1]); 
console.log(y[0]);
x[1] = 6789;
console.log(x[1]); 
console.log(y[0]);

2. 类型化数组

类型化数组类型表示可编制索引和操纵的 ArrayBuffer 对象 的各类视图。 全部数组类型的长度均固定。

名称 大小(以字节为单位) 描述
Int8Array 1 8 位二补码有符号整数
Uint8Array 1 8 位无符号整数
Int16Array 2 16 位二补码有符号整数
Uint16Array 2 16 位无符号整数
Int32Array 4 32 位二补码有符号整数
Uint32Array 4 32 位无符号整数
Float32Array 4 32 位 IEEE 浮点数
Float64Array 8 64 位 IEEE 浮点数

Int 就是整型,Uint 为无符号整形,Float 为浮点型,这些是 C 语言中的基本概念,我就不具体解释了。因为这些视图化结构都是大同小异,本文只对 Float32Array 类型做说明,读者能够触类旁通。
Float32Array 跟 Array 是十分相似的,只不过他每个元素都是都是一个 32位(4字节) 的浮点型数据。Float32Array 一旦建立其大小不能再修改。
咱们能够直接建立一个 Float32Array:

var x = new Float32Array(2);
x[0] = 17;
console.log(x[0]); // 17
console.log(x[1]); // 0
console.log(x.length); // 2

须要有这么一个概念,他依然是一个数组,只不过该数组中的每一个元素都是 Float 32 位的数据类型,再如:

var x = new Float32Array([17, -45.3]);
console.log(x[0]);  // 17
console.log(x[1]);  // -45.29999923706055
console.log(x.length); // 2

咱们把一个数组的值直接赋给了 x 这个 Float32Array 对象,那么在储存以前会将它转换成一个 32位浮点数。
因为该类数组的每一个元素都是同一类型,因此在堆栈模型中,他们所有会被压入到栈之中,所以类型化数组都是值类型,他并非引用类型!这个要引发注意,从下面的例子中也能够反映出来:

var x = new Float32Array([17, -45.3]);
var y = new Float32Array(x);
console.log(x[0]); // 17
console.log(x[1]); //-45.29999923706055
console.log(x.length); // 2
x[0] = -2;
console.log(y[0]); // 17, y的值没变

将 x 的值复制给 y,修改 x[0], y[0] 并无变化。
除了上面的方式,咱们还能够经过其余方式来建立一个类型化数组:

var buffer = new ArrayBuffer(12);
var x = new Float32Array(buffer, 0, 2);
var y = new Float32Array(buffer, 4, 1);
x[1] = 7;
console.log(y[0]); // 7

解释下这里为何返回 7.

ArrayBuffer(12)
+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|1|2|3|4|5|6|7|8| | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+
\              /           
  x (Float32Array)
  offset:0
  byteLength:4
  length:2


       ArrayBuffer(12)
+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|1|2|3|4|5|6|7|8| | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+
        \       /           
             y

看了上面的图解还有疑问么?我以为我不用继续解释了。能够把 ArrayBuffer 的单位当作 1,而 Float32Array 的单位是 4.

3. DataView对象

DataView 对象对数据的操做更加细致,不过我以为没啥意思,上面提到的各类类型化数组已经能够基本知足应用了,因此这里就一笔带过,一个简单的示例:

var buffer = new ArrayBuffer(12);
var x = new DataView(buffer, 0);
x.setInt8(0, 22);
x.setFloat32(1, Math.PI);
console.log(x.getInt8(0)); // 22
console.log(x.getFloat32(1)); // 3.1415927410125732

JavaScript中你所不知道的数组ArrayBufferJavaScript中你所不知道的数组ArrayBuffer

3、XHR2 中的 ArrayBuffer

ArrayBuffer 的应用特别普遍,不管是 WebSocket、WebAudio 仍是 Ajax等等,前端方面只要是处理大数据或者想提升数据处理性能,那必定是少不了 ArrayBuffer 。
XHR2 并非什么新东西,可能你用到了相关的特性,殊不知这就是 XHR2 的内容。最主要的一个东西就是 “xhr.responseType”,他的做用是设置响应的数据格式,可选参数有:"text"、"arraybuffer"、"blob"或"document"。请注意,设置(或忽略)xhr.responseType = '' 会默认将响应设为"text"。这里存在一个这样的对应关系:

请求            响应
text            DOMString
arraybuffer     ArrayBuffer
blob            Blob
document        Document

举个例子:

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
    // this.response == uInt8Array.buffer
    var uInt8Array = new Uint8Array(this.response); 
};

xhr.send();

咱们在 xhr.responseType 中设置了属性为 arraybuffer,那么在拿到的数据中就能够用类型化数组来接受啦!

4、小结

本文主要介绍了 Array 在堆栈模型中的存放方式,也详细描述了 ArrayBuffer 这个原始缓冲区的二进制数据类型,在 web 开发中,数据以及数据的储存是一个重要的部分,但愿引发注意!

5、参考资料

  • http://www.javascripture.com/ArrayBuffer
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array MDN Array
  • http://www.html5rocks.com/zh/tutorials/file/xhr2/ html5rocks
  • http://technet.microsoft.com/zh-cn/ie/br212485 MSDN

原文来自:http://xfenglin.com/a/12000457045.html

本文地址:http://www.linuxprobe.com/hidden-javascript-array.html

相关文章
相关标签/搜索