HTML5引入的新数组TypedArray介绍
来源:互联网 发布:乐嘉性格色彩测试算法 编辑:程序博客网 时间:2024/05/17 04:49
好吧,其实他是一个对象,比如我们可以这样去创建数组:
var array = new Array(10);
Javascript的数组的强大以及全能,给我们带来了便捷性。但一般而言:
全能的东西能在各种环境下使用,但却不一定适用于各种环境。
而TypedArray正是为了解决Javascript中数组“干太多事”而出现的。
起源TypedArray是一种通用的固定长度缓冲区类型,允许读取缓冲区中的二进制数据。
其在WEBGL规范中被引入用于解决Javascript处理二进制数据的问题。
TypedArray已经被大部分现代浏览器支持,例如可以用下面方法创建TypedArray:
// 创建一个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);
则缓冲和创建的引用布局为:
这表示Int32类型的v1数组的第0个元素是ArrayBuffer类型的b的第0-3个字节,如此等等。构造函数
上面我们通过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:
var array = new Uint8Array(10);
或者:
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
数据操作
TypedArray提供了setter、getter、set和subarray四个方法进行数据操作。
方法getter type get(unsigned long index)返回指定索引的元素。
setter void set(unsigned long index, type value)设置指定索引的元素为指定值。
void set(TypedArray array, optional unsigned long offset)void set(type[] array, optional unsigned long offset)根据array设置值,offset为偏移位置。
TypedArray subarray(long begin, optional long end)返回一个新的TypedArray,起始位为begin,结束位为end。
例如读取元素可以用:
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);alert(array[4]); //5设置元素可以用:
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);alert(array[4]); //5array[4] = 12;alert(array[4]); //12获取一个副本可以用:
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);var array2 = array.subarray(0);数组类型Int8Array
18位有符号整数byte
signed char
Uint8Array
18位无符号整数octet
unsigned char
Uint8ClampedArray
18位无符号整数 (clamped)octet
unsigned char
Int16Array
216位有符号整数short
short
Uint16Array
216位无符号整数unsigned short
unsigned short
Int32Array
432位有符号整数long
int
Uint32Array
432位无符号整数unsigned long
unsigned int
Float32Array
432位IEEE浮点数unrestricted float
float
Float64Array
864位IEEE浮点数unrestricted double
double
玩过canvas的可能会觉得很眼熟。
因为ImageData中用于存储图像数据的数组便是Uint8ClampedArray类型的。
例如:
var context = document.createElement("canvas").getContext("2d");var imageData = context.createImageData(100, 100);console.log(imageData.data);其在FireBug中显示为:
为什么要用TypedArrayUint8ClampedArray { 0=0, 1=0, 2=0, 更多...}
我们知道Javascript中数字是64位浮点数。则对于一个二进制图片(图片每个像素点是以8位无符号整数存储的),如果要将其数据在Javascript数组中使用,相当于使用了图片8倍的内存来存储一个图片的数据,这显然是不科学的。而TypedArray能帮助我们只使用原来1/8的内存来存储图片数据。
或者对于WebSocket,如果用base64进行传输也是一个花费较高的方式,转而使用二进制传送可能是更好的方式。
当然,TypedArray还有更多好处,比如具有更好的性能,下面我们进行一些小测试来验证这一点。
参与测试的浏览器为:
Test1:顺序读取速读FireFox 17.0.1 和 Chrome 23.0.1271.97m
var timeArray1 = [];
var timeArray2 = [];
function check1(){
var array = new Uint8ClampedArray(5000000);
for(var i = array.length; i--;){
array[i] = Math.floor(Math.random() * 100);
}
var temp;
var time1 = (new Date()).getTime();
for(var i = array.length; i--;){
temp = array[i];
}
var time2 = (new Date()).getTime();
console.log(time2 - time1);
timeArray1.push(time2 - time1);
}
function check2(){
var array2 = new Array(5000000);
for(var i = array2.length; i--;){
array2[i] = Math.floor(Math.random() * 100);
}
var temp;
var time3 = (new Date()).getTime();
for(var i = array2.length; i--;){
temp = array2[i];
}
var time4 = (new Date()).getTime();
console.log(time4 - time3);
timeArray2.push(time4 - time3);
}
function timer(__fun, __time, __callback){
var now = 0;
function begin(){
var timeout = setTimeout(function(){
if(now !== __time){
now++;
__fun();
begin();
}else{
if(timeArray1.length && timeArray2.length){
console.log("timeArray1 == " + timeArray1 + ", average == " + average(timeArray1));
console.log("timeArray2 == " + timeArray2 + ", average == " + average(timeArray2));
}
__callback && __callback();
}
}, 100);
}
begin();
}
function average(__array){
var total = 0;
for(var i = __array.length; i--;){
total += __array[i];
}
return (total / __array.length);
}
timer(check1, 10, function(){
timer(check2, 10);
});
可见Uint8ClampedArray的读取速度明显比Array要快(条状柱越长,代表花费时间越多)。
Test2:随机读取//……
function check1(){
var array = new Uint8ClampedArray(5000000);
for(var i = array.length; i--;){
array[i] = Math.floor(Math.random() * 100);
}
var temp;
var time1 = (new Date()).getTime();
for(var i = array.length; i--;){
temp = array[Math.floor(Math.random() * 5000000)];
}
var time2 = (new Date()).getTime();
console.log(time2 - time1);
timeArray1.push(time2 - time1);
}
function check2(){
var array2 = new Array(5000000);
for(var i = array2.length; i--;){
array2[i] = Math.floor(Math.random() * 100);
}
var temp;
var time3 = (new Date()).getTime();
for(var i = array2.length; i--;){
temp = array2[Math.floor(Math.random() * 5000000)];
}
var time4 = (new Date()).getTime();
console.log(time4 - time3);
timeArray2.push(time4 - time3);
}
//……
随即读取中Uint8ClampedArray的读取速度也是比Array要快的。
Test3:顺序写入//……
function check1(){
var array = new Uint8ClampedArray(5000000);
var time1 = (new Date()).getTime();
for(var i = array.length; i--;){
array[i] = Math.floor(Math.random() * 100);
}
var time2 = (new Date()).getTime();
console.log(time2 - time1);
timeArray1.push(time2 - time1);
}
function check2(){
var array2 = new Array(5000000);
var time3 = (new Date()).getTime();
for(var i = array2.length; i--;){
array2[i] = Math.floor(Math.random() * 100);
}
var time4 = (new Date()).getTime();
console.log(time4 - time3);
timeArray2.push(time4 - time3);
}
//……
Test4:复制操作(U8C to U8C 和 Array to U8C)
//……
function check1(){
var array = new Uint8ClampedArray(5000000);
for(var i = array.length; i--;){
array[i] = Math.floor(Math.random() * 100);
}
var temp;
var array2 = new Uint8ClampedArray(5000000);
var time1 = (new Date()).getTime();
array2.set(array);
var time2 = (new Date()).getTime();
console.log(time2 - time1);
timeArray2.push(time2 - time1);
}
function check2(){
var array = new Array(5000000);
for(var i = array.length; i--;){
array[i] = Math.floor(Math.random() * 100);
}
var temp;
var array2 = new Uint8ClampedArray(5000000);
var time1 = (new Date()).getTime();
array2.set(array);
var time2 = (new Date()).getTime();
console.log(time2 - time1);
timeArray2.push(time2 - time1);
}
//……
可见U8C复制到U8C,比Array复制到U8C快得多。
------------------------------------------------------------------------------------------
msdn上uint8Array介绍
Uint8Array 对象
8 位无符号整数值的类型化数组。内容将初始化为 0。如果无法分配请求数目的字节,则将引发异常。
语法
uint8Array = new Uint8Array( length );uint8Array = new Uint8Array( array );uint8Array = new Uint8Array( buffer, byteOffset, length);
参数
- uint8Array
必选。 Uint8Array 对象分配到的变量名称。
- length
指定数组中元素的数目。
- array
该数组中包含的数组(或类型化数组)。内容将初始化为给定数组或类型化数组的内容,且每个元素均转换为 Uint8 类型。
- buffer
Uint8Array 表示的 ArrayBuffer。
- byteOffset
可选。指定与 Uint8Array 将开始的缓冲区开始处的偏移量(以字节为单位)。
- length
数组中的元素数。
常量
下表列出了 Uint8Array 对象的常量。
常量
说明
BYTES_PER_ELEMENT 常量
数组中每个元素的大小(以字节为单位)。
属性
下表列出了 Uint8Array 对象的常量。
属性
说明
buffer 属性
只读。获取此数组引用的 ArrayBuffer。
byteLength 属性
只读。此数组距离其 ArrayBuffer 开始处的长度(以字节为单位),在构造时已固定。
byteOffset 属性
只读。此数组与其 ArrayBuffer 开始处的偏移量(以字节为单位),在构造时已固定。
length 属性
数组的长度。
方法
下表列出了 Uint8Array 对象的方法。
方法
说明
set 方法 (Uint8Array)
设置值或值数组。
subarray 方法 (Uint8Array)
为此数组获取 ArrayBuffer 存储的新 Uint8Array 视图。
以下示例演示如何使用 Uint8Array 对象处理从 XmlHttpRequest 获取的二进制数据:
var req = new XMLHttpRequest(); req.open('GET', "http://www.example.com"); req.responseType = "arraybuffer"; req.send(); req.onreadystatechange = function () { if (req.readyState === 4) { var buffer = req.response; var dataview = new DataView(buffer); var ints = new Uint8Array(buffer.byteLength); for (var i = 0; i < ints.length; i++) { ints[i] = dataview.getUint8(i); } alert(ints[10]); } }
要求
在以下文档模式中受支持:Internet Explorer 10 标准模式和 Internet Explorer 11 标准模式。此外,也在应用商店应用(Windows 8 和 Windows Phone 8.1)中受支持。请参阅版本信息。
在以下文档模式中不受支持:Quirks、Internet Explorer 6 标准模式、Internet Explorer 7 标准模式、Internet Explorer 8 标准模式、Internet Explorer 9 标准模式。
- HTML5引入的新数组TypedArray介绍
- HTML5引入的新数组TypedArray介绍
- HTML5引入的新数组TypedArray介绍
- HTML5 Draft 的一些新特性介绍
- html5新特性的介绍和总结
- html5样式的引入
- HTML5新特性介绍
- html5新特性介绍
- HTML5新特性介绍
- html5新标签介绍
- ios7中引入的新类:nsprogress介绍
- html5介绍,什么是html5,html5新特性
- html5学习笔记---01.HTML5介绍,02.HTML5的新特性
- 不引入新的数组,实现数组元素交换位置函数
- JavaScript 1.6 引入了几个新的Array (数组)方法
- html5的新特性
- html5的新特性
- HTML5的新特性
- Android 应用瘦身,从 18MB 到 12.5MB
- java 算法 单链表 栈 树 图
- IOS开发--应用程序图标数字角标
- 猴子吃桃问题
- 2017进修计划
- HTML5引入的新数组TypedArray介绍
- P1372
- ListView的item点击无响应,onItemClick()没被调用
- Ajax,$.ajax使用实例详解
- jquery笔记:$(html)
- nodejs时间处理工具momentjs
- hdu 1286 欧拉函数模版题
- J2EE之RMI
- 蓝桥杯 ——2的次幂表示