1. 程式人生 > 其它 >淺析JavaScript型別化陣列TypedArray理解、為什麼使用TypedArray、型別陣列與普通陣列的區別及其常見應用(處理二進位制資料型別)

淺析JavaScript型別化陣列TypedArray理解、為什麼使用TypedArray、型別陣列與普通陣列的區別及其常見應用(處理二進位制資料型別)

  Javascript 中的陣列是個強大的傢伙:你可以建立的時候不規定長度,而是動態的去改變長度。你可以把他當成普通的陣列去讀取,也可以當他是堆疊來使用。你可以改變陣列中每個元素的值甚至是型別。其實它是一個物件,比如我們可以這樣去建立陣列:var array = new Array(10);

  Javascript 的陣列的強大以及全能,給我們帶來了便捷性。但一般而言:全能的東西能在各種環境下使用,但卻不一定適用於各種環境。而 TypedArray 正是為了解決Javascript 中陣列“幹太多事”而出現的。

一、什麼是型別化陣列

  在定製 html5 版本中,TypedArray是一種通用的固定長度緩衝區型別,允許讀取緩衝區中的二進位制資料。其在WEBGL規範中被引入用於解決Javascript處理二進位制資料的問題。型別化陣列也是陣列,只不過其元素被設定為特定型別的值。

  型別化陣列的核心就是一個名為 ArrayBuffer 的型別。每個ArrayBuffer物件表示的只是記憶體中指定的位元組數,但不會指定這些位元組用於儲存什麼型別的資料。通過ArrayBuffer能做的,就是為了將來使用而分配一定數量的位元組。

// 建立一個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);

1、型別陣列:描述的是二進位制快取區一個類似陣列的檢視

2、建構函式:上面我們通過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

  我們知道Javascript中數字是64位浮點數。則對於一個二進位制圖片(圖片每個畫素點是以8位無符號整數儲存的),如果要將其資料在Javascript陣列中使用,相當於使用了圖片8倍的記憶體來儲存一個圖片的資料,這顯然是不科學的。而TypedArray能幫助我們只使用原來1/8的記憶體來儲存圖片資料。

  或者對於WebSocket,如果用base64進行傳輸也是一個花費較高的方式,轉而使用二進位制傳送可能是更好的方式。

  當然,TypedArray還有更多好處,比如具有更好的效能,下面我們進行一些小測試來驗證這一點。

1、順序讀取速讀

2、隨機讀取

3、順序寫入

4、複製操作

  可以看到效能均比 Array 要好。詳見這篇文章:https://www.jb51.net/html5/68844.html

三、TypedArray和陣列的區別

四、實際應用

  傳統意義上服務通過AJAX只能返回文字資料,responseType預設是一個text,但是在xhr中,可以設定為一個二進位制資料,只需要將responseType設定成arraybuffer

var xhr=new XMLHttpRequest();
xhr.open("GET","/myfile.png",true);
xhr.responseType="arraybuffer";
 
xhr.onload=function (oEvent) {
    var arrayBuffer=xhr.response;
    if (arrayBuffer){
        var byteArray=new Uint8Array(arrayBuffer)
        for (var i=0;i<byteArray.byteLength;i++){
            //對陣列中每個元素進行操作
        }
    }
}
xhr.send(null)

  其他應用平時確實用的不多,以後遇到可以考慮看看。