類型化數組(Typed Array)也是HTML5中新引入的API。用一句話解釋類型化數組就是:它是JS操做二進制數據的接口。 衆所周知,直接操做二進制數據可使程序更爲高效, 儘管JS對常規數組作了不少優化(JS數組被實現爲對象形式),可是不得不認可JS數組的效率一直不高。好比在WebGL中的圖像數據傳輸, 若是使用原生的JS數組, 瀏覽器在與顯卡通訊時,必須將它轉換爲二進制形式,這一步較爲耗時。正是由於有大量二進制數據的操做需求,因此ArrayBuffer應運而生。在Canvas(可參考本人canvas筆記canvas的基本原理)中,使用getImageDate()
方法所返回的ImageData
對象就是一個類數組對象,HTML標準中稱其爲CanvasPixelArray
,它除了在值的處理方式上與ArrayBuffer
中視圖類型Unit8Array
有點區別外,其餘都同樣(Unit8Array
只能處理0-255的數字,而CanvasPixelArray
能夠處理更多)編程
對於剛接觸類型化數組的概念看到這可能仍是雲裏霧裏,下面將逐一將我所理解的ArrayBuffer中的關鍵概念作個整理:canvas
大多數資料中對於視圖都是一句帶過,好比這篇博客中(ArrayBuffer:類型化數組)對於視圖的解釋就是:segmentfault
ArrayBuffer做爲內存區域,能夠存放多種類型的數據。不一樣數據有不一樣的存儲方式,這就叫作「視圖」。數組
當我剛看到上面的解釋,仍是沒法體會「視圖」的含義,暫且把ArrayBuffer的概念放一邊, 想象一下,既然是操做二進制數據的接口,那麼該如何操做他們呢, 好比8位二進制數1是00000001
,咱們確定不會使用原始的二進制編程,那麼當咱們操做這個1
時,確定是以1
的形式操做, 那麼這裏的1
就是視圖(view)了, 視圖能夠理解爲方便理解的二進制數據。若是知道C語言,對於這個概念就不難把握了,好比C語言中的字符串實際是數字,那麼這裏的字符串也能夠理解爲「視圖」。其實這裏的視圖就是類型化數組。瀏覽器
ArrayBuffer是一段不透明的內存區域(所謂不透明,就是沒法直接操做的數據塊),單位是字節(Byte)也就是8位,它的byteLength
屬性返回其內存大小。在JS中,經過構造函數的形式申明一段ArrayBuffer區域:網絡
var a = new ArrayBuffer(10) a.byteLength // =>10
在這段內存區域上,可使用不一樣的視圖來建立任意數量的類型化數組, 這些類型化數組也能夠是重疊的。有八種不一樣的類型化數組(視圖),分別爲:架構
Int8Array:8位有符號整數,長度1個字節。函數
Uint8Array:8位無符號整數,長度1個字節。優化
Int16Array:16位有符號整數,長度2個字節。.net
Uint16Array:16位無符號整數,長度2個字節。
Int32Array:32位有符號整數,長度4個字節。
Uint32Array:32位無符號整數,長度4個字節。
Float32Array:32位浮點數,長度4個字節。
Float64Array:64位浮點數,長度8個字節。
這裏引用這篇博客中(JavaScript中的ArrayBuffer詳細介紹)的例子來解釋ArrayBuffer區域中出現的重疊(也叫複合視圖)現象:
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
原文中做者的解釋過於簡單。這裏的y[0]
之因此爲7,是由於在buffer
這段12個字節的內存區域中,申明來一個從0字節開始,長度爲2的32位浮點數x
(也就是說x佔了前8個字節),再申明一個從第4
個字節開始,長度爲1的32位浮點數y
,那麼這裏的y
與x
實際上就是重疊的,x
已經佔了8個字節,而y
是從第4個字節開始的。既然是重疊的,那麼改變x
勢必會影響到y
,這裏x
類型化數組的第一個元素賦值爲7,那麼在ArrayBuffer中便是00000000 00000000 00000000 00000111
而y
是從第四個字節開始,也就是從00000111
開始, 因此y
也是00000111
也就是7了。
類型化數組實質上是二進制數據,而ArrayBuffer這段區域又是指定長度的,基於這些即可推出其與常規數組的區別:
類型化數組元素都是數字,它不像JS常規數組那樣能夠參雜不一樣類型,好比下面例子?中的賦值就是無效的
類型化數組長度固定
全部元素初始化爲0
var a = new Int8Array(3) a[0] = 'hello' a[0] // =>0 顯示a[0]依然未定義 a[0] = '8' a[0] // = > 8 可是注意類型的自動轉換,當可被轉換成數字時,JS會自動將其轉成數值
既然本質是在操做二進制數據,那麼就涉及到「高位優先(big-endian)」仍是「低位優先(little-endian)」的數據傳輸問題,DataView的一整套API中就涉及到解決該問題,在當前的大部分CPU架構中的字節傳輸順序都是使用低位優先,而在大部分的網絡協議中使用的字節順序倒是高位優先(好比HTTP協議),它的一系列get方法中就能夠設置字節的處理順序。DataView也是一種視圖,它的原理並不難,詳細的dataview的API能夠看前面提到的博客中的DataView章節。mark?ArrayBuffer:類型化數組
二進制數據的接口主要應用於文件,在JS中涉及文件處理的API幾乎均可以應用ArrayBuffer,主要是Ajax,File,Canvas。這幾個例子等下再碼,爭取寫出跟前面博客不同的東西,先搬磚……