国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 網(wǎng)站 > WEB開發(fā) > 正文

HTML5引入的新數(shù)組TypedArray介紹

2024-04-27 15:05:47
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
avascript中的數(shù)組是個(gè)強(qiáng)大的家伙:你可以創(chuàng)建的時(shí)候不規(guī)定長(zhǎng)度,而是動(dòng)態(tài)的去改變長(zhǎng)度。你可以把他當(dāng)成普通的數(shù)組去讀取,也可以當(dāng)他是堆棧來(lái)使用。你可以改變數(shù)組中每個(gè)元素的值甚至是類型javascript中的數(shù)組是個(gè)強(qiáng)大的家伙:你可以創(chuàng)建的時(shí)候不規(guī)定長(zhǎng)度,而是動(dòng)態(tài)的去改變長(zhǎng)度。你可以把他當(dāng)成普通的數(shù)組去讀取,也可以當(dāng)他是堆棧來(lái)使用。你可以改變數(shù)組中每個(gè)元素的值甚至是類型。

好吧,其實(shí)他是一個(gè)對(duì)象,比如我們可以這樣去創(chuàng)建數(shù)組:

復(fù)制代碼代碼如下:var array = new Array(10);Javascript的數(shù)組的強(qiáng)大以及全能,給我們帶來(lái)了便捷性。但一般而言:

全能的東西能在各種環(huán)境下使用,但卻不一定適用于各種環(huán)境。

而TypedArray正是為了解決Javascript中數(shù)組“干太多事”而出現(xiàn)的。

起源

TypedArray是一種通用的固定長(zhǎng)度緩沖區(qū)類型,允許讀取緩沖區(qū)中的二進(jìn)制數(shù)據(jù)。

其在WEBGL規(guī)范中被引入用于解決Javascript處理二進(jìn)制數(shù)據(jù)的問題。

TypedArray已經(jīng)被大部分現(xiàn)代瀏覽器支持,例如可以用下面方法創(chuàng)建TypedArray:

復(fù)制代碼代碼如下:// 創(chuàng)建一個(gè)8-byte的ArrayBuffervar b = new ArrayBuffer(8);// 創(chuàng)建一個(gè)b的引用,類型是Int32,起始位置在0,結(jié)束位置為緩沖區(qū)尾部var v1 = new Int32Array(b);// 創(chuàng)建一個(gè)b的引用,類型是Uint8,起始位置在2,結(jié)束位置為緩沖區(qū)尾部var v2 = new Uint8Array(b, 2);// 創(chuàng)建一個(gè)b的引用,類型是Int16,起始位置在2,總長(zhǎng)度為2var v3 = new Int16Array(b, 2, 2);則緩沖和創(chuàng)建的引用布局為:
變量索引
 字節(jié)數(shù)
b =01234567
 索引數(shù)
v1 =01
v2 = 012345
v3 = 01 
這表示Int32類型的v1數(shù)組的第0個(gè)元素是ArrayBuffer類型的b的第0-3個(gè)字節(jié),如此等等。構(gòu)造函數(shù)

上面我們通過ArrayBuffer來(lái)創(chuàng)建TypedArray,而實(shí)際上,TypedArray提供了3個(gè)構(gòu)造函數(shù)來(lái)創(chuàng)建他的實(shí)例。

構(gòu)造函數(shù)復(fù)制代碼代碼如下:TypedArray(unsigned long length)創(chuàng)建一個(gè)新的TypedArray,length是其固定長(zhǎng)度。復(fù)制代碼代碼如下:TypedArray(TypedArray array)TypedArray(type[] array)創(chuàng)建一個(gè)新的TypedArray,其每個(gè)元素根據(jù)array進(jìn)行初始化,元素進(jìn)行了相應(yīng)的類型轉(zhuǎn)換。復(fù)制代碼代碼如下:TypedArray(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long length)創(chuàng)建一個(gè)新的TypedArray,使其作為buffer的一個(gè)引用,byteOffset為其起始的偏移量,length為其長(zhǎng)度。所以通常我們用下面的方式創(chuàng)建TypedArray:復(fù)制代碼代碼如下:var array = new Uint8Array(10);或者:復(fù)制代碼代碼如下:var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 數(shù)據(jù)操作

TypedArray提供了setter、getter、set和subarray四個(gè)方法進(jìn)行數(shù)據(jù)操作。

方法getter type get(unsigned long index)

返回指定索引的元素。

setter void set(unsigned long index, type value)

設(shè)置指定索引的元素為指定值。

void set(TypedArray array, optional unsigned long offset)void set(type[] array, optional unsigned long offset)

根據(jù)array設(shè)置值,offset為偏移位置。

TypedArray subarray(long begin, optional long end)

返回一個(gè)新的TypedArray,起始位為begin,結(jié)束位為end。

例如讀取元素可以用

var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);alert(array[4]); //5

設(shè)置元素可以用

var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);alert(array[4]); //5array[4] = 12;alert(array[4]); //12

獲取一個(gè)副本可以用

var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);var array2 = array.subarray(0);數(shù)組類型

類型大小描述Web IDL類型C 類型
Int8Array18位有符號(hào)整數(shù)bytesigned char
Uint8Array18位無(wú)符號(hào)整數(shù)octetunsigned char
Uint8ClampedArray18位無(wú)符號(hào)整數(shù) (clamped)octetunsigned char
Int16Array216位有符號(hào)整數(shù)shortshort
Uint16Array216位無(wú)符號(hào)整數(shù)unsigned shortunsigned short
Int32Array432位有符號(hào)整數(shù)longint
Uint32Array432位無(wú)符號(hào)整數(shù)unsigned longunsigned int
Float32Array432位IEEE浮點(diǎn)數(shù)unrestricted floatfloat
Float64Array864位IEEE浮點(diǎn)數(shù)unrestricted doubledouble
玩過canvas的可能會(huì)覺得很眼熟。

因?yàn)镮mageData中用于存儲(chǔ)圖像數(shù)據(jù)的數(shù)組便是Uint8ClampedArray類型的。

例如:

var context = document.createElement("canvas").getContext("2d");var imageData = context.createImageData(100, 100);console.log(imageData.data);

其在FireBug中顯示為

Uint8ClampedArray { 0=0, 1=0, 2=0, 更多...}

為什么要用TypedArray

我們知道Javascript中數(shù)字是64位浮點(diǎn)數(shù)。則對(duì)于一個(gè)二進(jìn)制圖片(圖片每個(gè)像素點(diǎn)是以8位無(wú)符號(hào)整數(shù)存儲(chǔ)的),如果要將其數(shù)據(jù)在Javascript數(shù)組中使用,相當(dāng)于使用了圖片8倍的內(nèi)存來(lái)存儲(chǔ)一個(gè)圖片的數(shù)據(jù),這顯然是不科學(xué)的。而TypedArray能幫助我們只使用原來(lái)1/8的內(nèi)存來(lái)存儲(chǔ)圖片數(shù)據(jù)。

或者對(duì)于WebSocket,如果用base64進(jìn)行傳輸也是一個(gè)花費(fèi)較高的方式,轉(zhuǎn)而使用二進(jìn)制傳送可能是更好的方式。

當(dāng)然,TypedArray還有更多好處,比如具有更好的性能,下面我們進(jìn)行一些小測(cè)試來(lái)驗(yàn)證這一點(diǎn)。

參與測(cè)試的瀏覽器為

Firefox 17.0.1 和 Chrome 23.0.1271.97m

Test1:順序讀取速讀復(fù)制代碼代碼如下: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要快(條狀柱越長(zhǎng),代表花費(fèi)時(shí)間越多)。

Test2:隨機(jī)讀取復(fù)制代碼代碼如下://……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:順序?qū)懭?/strong>復(fù)制代碼代碼如下://……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:復(fù)制操作(U8C to U8C 和 Array to U8C)

復(fù)制代碼代碼如下://……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復(fù)制到U8C,比Array復(fù)制到U8C快得多。

------------------------------------------------------------------------------------------

msdn上uint8Array介紹

Uint8Array 對(duì)象

 

8 位無(wú)符號(hào)整數(shù)值的類型化數(shù)組。內(nèi)容將初始化為 0。如果無(wú)法分配請(qǐng)求數(shù)目的字節(jié),則將引發(fā)異常。

語(yǔ)法

      uint8Array = new Uint8Array( length );uint8Array = new Uint8Array( array );uint8Array = new Uint8Array( buffer, byteOffset, length);

參數(shù)

uint8Array

必選。 Uint8Array 對(duì)象分配到的變量名稱。

length

指定數(shù)組中元素的數(shù)目。

array

該數(shù)組中包含的數(shù)組(或類型化數(shù)組)。內(nèi)容將初始化為給定數(shù)組或類型化數(shù)組的內(nèi)容,且每個(gè)元素均轉(zhuǎn)換為 Uint8 類型。

buffer

Uint8Array 表示的 ArrayBuffer。

byteOffset

可選。指定與 Uint8Array 將開始的緩沖區(qū)開始處的偏移量(以字節(jié)為單位)。

length

數(shù)組中的元素?cái)?shù)。

常量

下表列出了 Uint8Array 對(duì)象的常量。

常量

說(shuō)明

BYTES_PER_ELEMENT 常量

數(shù)組中每個(gè)元素的大小(以字節(jié)為單位)。

屬性

下表列出了 Uint8Array 對(duì)象的常量。

屬性

說(shuō)明

buffer 屬性

只讀。獲取此數(shù)組引用的 ArrayBuffer。

byteLength 屬性

只讀。此數(shù)組距離其 ArrayBuffer 開始處的長(zhǎng)度(以字節(jié)為單位),在構(gòu)造時(shí)已固定。

byteOffset 屬性

只讀。此數(shù)組與其 ArrayBuffer 開始處的偏移量(以字節(jié)為單位),在構(gòu)造時(shí)已固定。

length 屬性

數(shù)組的長(zhǎng)度。

  

方法

下表列出了 Uint8Array 對(duì)象的方法。

方法

說(shuō)明

set 方法 (Uint8Array)

設(shè)置值或值數(shù)組。

subarray 方法 (Uint8Array)

為此數(shù)組獲取 ArrayBuffer 存儲(chǔ)的新 Uint8Array 視圖。

以下示例演示如何使用 Uint8Array 對(duì)象處理從 xmlHttPRequest 獲取的二進(jìn)制數(shù)據(jù):

JavaScript
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 標(biāo)準(zhǔn)模式和 Internet Explorer 11 標(biāo)準(zhǔn)模式。此外,也在應(yīng)用商店應(yīng)用(Windows 8 和 Windows Phone 8.1)中受支持。請(qǐng)參閱版本信息。

在以下文檔模式中不受支持:Quirks、Internet Explorer 6 標(biāo)準(zhǔn)模式、Internet Explorer 7 標(biāo)準(zhǔn)模式、Internet Explorer 8 標(biāo)準(zhǔn)模式、Internet Explorer 9 標(biāo)準(zhǔn)模式。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 余姚市| 炎陵县| 子长县| 龙岩市| 镇坪县| 永济市| 宁化县| 育儿| 灯塔市| 白朗县| 黄大仙区| 莱阳市| 玉溪市| 中山市| 兴城市| 垣曲县| 东方市| 沙雅县| 白银市| 萨迦县| 闸北区| 海阳市| 南昌市| 海城市| 河间市| 靖宇县| 天全县| 汉源县| 齐河县| 屏边| 化州市| 林芝县| 宿州市| 山阳县| 洪洞县| 会理县| 巴楚县| 百色市| 菏泽市| 东城区| 金塔县|