| 导读 | 相信每一个 javascript 学习者,都会去了解 JS 的各种基本数据类型,数组就是数据的组合,这是一个很基本也十分简单的概念,他的内容没多少,学好它也不是件难事情。但是本文着重要介绍的并不是我们往常看到的 Array,而是 ArrayBuffer。 |
前段时间一直在研究 Web Audio API 以及语音通信相关的知识,内容侧重于音频流在 AudioContext 各个节点之间的流动情况,而现在要摸清楚音频到流底是个什么样的数据格式,所以对 ArrayBuffer 的研究就显得格外重要了。
Javascript 中如何产生 Array:
[element0, element1, ..., elementN] new Array(element0, element1, ..., elementN) new Array(arrayLength)
直接定义,或者通过构造函数创建一个 Array,当然也可以使用其他的手段:
"array".split("");
"array".match(/a|r/g);
等等,方式有很多。但是 Array 内部是个什么样的结构,恐怕很多人还不是很清楚。
在数组中我们可以放很多不同数据类型的数据,如:
var arr = [21, "李靖", new Date(), function(){}, , null];
上面这个数组中一次放入了 数字、字符串、对象、函数、undefined 和 null,对于上面的数据接口我们可以具象的描述下:
栈 +---------+ 堆 | 21 | +-------------------+ +---------+ | | | "李靖" | | | +---------+ | +--------+ | | [refer] |----------->| Object | | +---------+ | +--------+ | | [refer] |----------------->+--------+ | +---------+ | |function| | |undefined| | +--------+ | +---------+ | | | null | +-------------------+ +---------+ Created By Barret Lee
JavaScript 的数据类型分为两种,一种是值类型,一种是引用类型,常见的引用类型有 Object 和 Array,数组的储存模型中,如果是诸如 Number、String 之类的值类型数据会被直接压入栈中,而引用类型只会压入对该值的一个索引,用 C 语言的概念来解释就是只保存了数据的指针,这些数据是储存在堆中的某块区间中。栈堆并不是独立的,栈也可以在堆中存放。
好了,对 Array 的说明就到这里,下面具体说说 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 是弱类型语言,但是他本身是对数据的类型和大小都有限制的,我们需要通过某种数据结构将缓冲区的内容有序的读取出来(写进去)。
var buffer = new ArrayBuffer(30);从 chrome 控制台可以看到: []({{ 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]);
| 名称 | 大小(以字节为单位) | 描述 |
|---|---|---|
| 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 浮点数 |
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.
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
请求 响应 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,那么在拿到的数据中就可以用类型化数组来接受啦!
- 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://www.linuxprobe.com/hidden-javascript-array.html
免费提供最新Linux技术教程书籍,为开源技术爱好者努力做得更多更好:http://www.linuxprobe.com/
本文探讨了ArrayBuffer在JavaScript中的作用及其实现原理,包括其内存模型、创建方式、类型化数组以及DataView对象的使用,并介绍了ArrayBuffer在XHR2中的应用。
1285

被折叠的 条评论
为什么被折叠?



