ArrayBuffer

转自:http://www.cnblogs.com/hustskyking/p/javascript-array.html

一、Array 在内存中的堆栈模型

1. Array 的获取

Javascript 中如何产生 Array:

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

直接定义,或者通过构造函数创建一个 Array,当然也可以使用其他的手段:

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

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

2. 堆栈模型

在数组中我们可以放很多不同数据类型的数据,如:

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

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

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

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

二、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 控制台可以看到:

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 对象 的各种视图。 所有数组类型的长度均固定。

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

如果感兴趣,可以移步http://www.javascripture.com/DataView,作详细了解。

三、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,那么在拿到的数据中就可以用类型化数组来接受啦!

四、参考资料

  • 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
时间: 2024-10-15 17:06:12

ArrayBuffer的相关文章

ArrayBuffer and Base64

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="wid

ArrayBuffer:类型化数组 (转)

ArrayBuffer:类型化数组 来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 目录 分配内存 视图 视图的生成 视图的操作 复合视图 DataView视图 应用 Ajax Canvas File 参考链接 类型化数组是JavaScript操作二进制数据的一个接口. 这要从WebGL项目的诞生说起,所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的.实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式.

ArrayBuffer和TypedArray,以及Blob的使用

前端使用TypedArray编辑二进制 ES6提供了, ArrayBuffer和TypedArray, 让前端也可以直接操作编辑二进制数据, 网页中的类型为file的input标签, 也可以通过FileReader转化为二进制, 然后再做编辑等, 本文提供参考: ArrayBuffer : 代表内存之中的一段二进制数据, 通过它我们可以直接创建二进制对象,然后使用相关的方法和属性. 如何使用ArrayBuffer: new ArrayBuffer(32), 从内存中申请32个字节: 把Array

ArrayBuffer类型化数组

类型化数组是JavaScript操作二进制数据的一个接口 这要从WebGL项目的诞生说起,所谓WebGL就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的.实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式.比如,以文本格式传递一个32位整数,两端的JavaScript脚本与 显卡都要进行格式转化,非常耗时.这时要是存在一种机制,可以像C语言那样,直接操作字节,然后将4个字节的32位整数,以二进制形式原封不动的送入显卡,脚本的性能就会大幅提升.类

HTML5 Blob与ArrayBuffer、TypeArray和字符串String之间转换

1.将String字符串转换成Blob对象 //将字符串 转换成 Blob 对象 var blob = new Blob(["Hello World!"], { type: 'text/plain' }); console.info(blob); console.info(blob.slice(1, 3, 'text/plain')); 2.将TypeArray  转换成 Blob 对象 //将 TypeArray 转换成 Blob 对象 var array = new Uint16A

Scala 深入浅出实战经典 第39讲:ListBuffer、ArrayBuffer、Queue、Stack操作代码实战

王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2 技术爱好者尤其是大数据爱好者 可以加DT大数据梦工厂的qq群 DT大数据梦工厂① :462923555 DT大数据梦工厂②:437123764 DT大数据梦工厂③

ArrayBuffer简析

关键技术: JavaScript,ArrayBuffer,Type Array,DataView,Web Worker,性能对比 ArrayBuffer 在文章开头列出了这些关键字,主要就是让大家了解本文的主要内容,如果你不感兴趣转发了就可以走:如果对这一块非常了解,欢迎多提意见多交流:如果想这方面的技术一见钟情,那不妨坐下了可以享受阅读的乐趣. 首先,为什么Web开发者需要不断优化数据的传输?因为数据是应用的核心,因这一块直接决定了用户体验的好与坏,而用户的本性是贪婪的.用户的需求随着自身满意

TypeArray、ArrayBuffer、Blob、File、DataURL、canvas的相互转换

原文地址: http://www.shihua.im/2015/12/29/20151229_arrayBuffer/ http://blog.csdn.net/cuixiping/article/details/45932793 Blob to ArrayBuffer var blob = new Blob([data], {type: 'text/plain'}); var reader = new FileReader(); reader.onload = function(e) { ca

javascript ArrayBuffer类型化数组和视图的操作

个人理解类型化数据就是内存分配区域,不同数据的存储就是视图DataView咯 var buffers = []; var json = {"id":100, "name": "中国"};var buf = new Buffer(JSON.stringify(json)); 定义一个ArrayBuffer var ab = new ArrayBuffer(6);//定义一个6字节的内存区域 var abLength =  ab.byteLength