問題來由:
之前面試X公司的時候,問我關於原型鏈知道多少,於是我就開始說了一些有關於原型鏈的東西,面試官問Array的原型是什么,我說是對象,畢竟Array.prototype===array.__proto__是一樣的嘛,但是我忽略了一個問題,就是這個對象是類數組對象,我想面試官可能要問我這個吧,總結一下。
什么是數組:
JavaScript的基本數據類型,即Array。
判斷目標對象是不是Array:
(1)構造函數判斷
target.constructor === Array
(2)instanceof判斷
target instanceof Array
注:別用typeof。只能判斷為Object
什么是類數組:
與數組一樣具有length與index屬性,但是本質確實個Object,最常見的就是arguments
target.constructor === Object
擴展:類數組有什么優點
提供了一種用於訪問原始二進制數據的機制。 正如你可能已經知道,Array存儲的對象能動態增多和減少,並且可以存儲任何JavaScript值。JavaScript引擎會做一些內部優化,以便對數組的操作可以很快。然而,隨着Web應用程序變得越來越強大,尤其一些新增加的功能例如:音頻視頻編輯,訪問WebSockets的原始數據等,很明顯有些時候如果使用JavaScript代碼可以快速方便地通過類型化數組來操作原始的二進制數據將會非常有幫助(來自MDN)
類型數組架構(緩沖和視圖):
(圖片來自於MDN)
緩沖:
用ArrayBuffer對象實現,不提供機制訪問內容,視圖提供了上下文 — 即數據類型、起始偏移量和元素數 — 將數據轉換為實際有類型的數組。
ArrayBuffer:一個通用的、固定長度的二進制數據緩沖區。
你不能直接操縱一個ArrayBuffer中的內容,你需要創建一個類型化數組的視圖或一個描述緩沖數據格式的DataView,使用它們來讀寫緩沖區中的內容。
視圖:
DataView是一種底層接口,它提供有可以操作緩沖區中任意數據的讀寫接口。這對操作不同類型數據的場景很有幫助,例如:類型化數組視圖都是運行在本地字節序模式(參考 Endianness),可以通過使用 DataView
來控制字節序。默認是大端字節序(Big-endian),但可以調用讀寫接口改為小端字節序(Little-endian)。
類型化數組視圖具有自描述性的名字和所有常用的數值類型像Int8
,Uint32
,Float64
等等。有一種特殊類型的數組Uint8ClampedArray
。它僅操作0到255之間的數值。
例如,這對於Canvas數據非常有用。詳見:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Typed_arrays
栗子:
創建緩沖區
//首先,我們創建一個16字節固定長度的緩沖 var buffer = new ArrayBuffer(16);
基於buffer創建視圖1
//視圖1,視圖將把緩沖內的數據格式化為一個32位的有符號整數數組 var int32View = new Int32Array(buffer);
填充視圖1
//填充數組 for (var i = 0; i < int32View.length; i++) { int32View[i] = i * 2; }
輸出結果
創建視圖2,這里視圖是2字節整數視圖,與上面4字節整數視圖共享同一個緩沖區。
//視圖2 var int16View = new Int16Array(buffer);
輸出視圖2:
console.dir(int16View)
結果:
可以看到兩個視圖對同一緩沖區的數據以不同格式展示出來
復雜的數據結構:
struct someStruct { unsigned long id; char username[16]; float amountDue; };
C語言結構體中包含復雜類型,用類結構體緩沖:
var buffer = new ArrayBuffer(24); // ... read the data into the buffer ... var idView = new Uint32Array(buffer, 0, 1); var usernameView = new Uint8Array(buffer, 4, 16); var amountDueView = new Float32Array(buffer, 20, 1);
轉化為普通數組:
var typedArray = new Uint8Array([1, 2, 3, 4]), normalArray = Array.prototype.slice.call(typedArray); normalArray.length === 4; normalArray.constructor === Array;
注:該篇文章與MDN基本類似,這里做個記錄,想了解更多MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Typed_arrays