摘要:在內部設計時分成了兩部分和。層表示內存中的數據塊,負責提供操作數據塊的接口。也就是說通過創建內存塊,通過實現對內存塊的讀寫操作。很顯然中的結果是。有同學可能對輸出的順序不理解,覺得為什么不是呢。上例在小端模式下的存儲形式,每個框框表示位。
我們知道在C語言中,可以使用malloc和free方法來分配和釋放內存。隨著web的發展中,js在ES6中新增了內存操作的支持。其實現方式就是---typed array。
typed array是個集體的概念。int8Array,Uint8Array,int16Array,Uint16Array等統統等稱為typed array。通過這些類,開發者可以方便地讀寫內存中的二進制數據。
typed array在內部設計時分成了兩部分:buffer和view。buffer層表示內存中的數據塊,view負責提供操作數據塊的接口。
ArrayBufferbuffer層的底層實現就是基于ArrayBuffer類。ArrayBuffer的功能與malloc類似,為用戶分配一塊內存。
創建一個ArrayBuffer實例很簡單,它接收一個參數,參數表示要分配多大的一塊內存區域,字節為單位。下面的代碼片段,分配了一塊8字節的內存區:
var buffer = new ArrayBuffer(8);
我們還可以通過byteLength訪問該實例的內存大小:
console.log(buffer.byteLength) // 8
使用slice方法創建一個新的實例,其內容復制原ArrayBuffer實例中的部分內容。
var buf2 = buffer.slice(0,2);
創建一個新的實例,分配2字節大小的內存,其內容復制buffer中索引為0和1的內存中的數據。
但是ArrayBuffer并不提供對內存讀寫的方法。如果要對該內存塊進行操作,需要用到另一個類DataView。
DataViewDataView類提供了訪問ArrayBuffer的接口。其語法如下:
new DataView(buffer [, byteOffset [, byteLength]])
首先接收一個必傳的buffer對象,該對象就是DataView實例接下來將要操作的內存塊。其次是一個可選的byteOffset,該參數表示DataView實例要操作的buffer對象的開始位置。最后的參數指定要操作的buffer對象中元素的個數。
下面的代碼片段演示了DataView如何操作ArrayBuffer:
var buffer = new ArrayBuffer(16); var dv = new DataView(buffer, 0); dv.setInt16(1, 42); dv.getInt16(1); //42
示例中創建了一個DataView實例,該實例將buffer作為被操作的內存塊,并且指定該內存塊的16個字節都位于可操作區。
接著調用setInt16方法向從buffer的第2個字節開始存儲帶符號的16位整數。調用getInt16方法讀出位于第2個字節處的帶符號的16位整數。
如上所述,typed array的實現是組合了ArrayBuffer和DataView。也就是說typed array 通過ArrayBuffer創建內存塊,通過DataView實現對內存塊的讀寫操作。
typed array提供了多個類實現對同一塊內存中的二進制數據按照不同的位數格式進行讀寫。如使用int8Array從內存中以帶符號的8位整數的形式讀寫數據。
下面看一個例子來加深對typed array的理解
var buffer = new ArrayBuffer(16) //創建16b的內存區 var int32View = new Int32Array(buffer); var int16View = new Int16Array(buffer); for (var i = 0; i < int32View.length; i++) { int32View[i] = i * 2; console.log(int32View[i]); // 0, 2, 4, 6 } for (var i = 0; i < int16View.length; i++) { console.log(int16View[i]); // 0, 0, 2, 0, 4, 0, 6, 0 }
buffer是一個ArrayBuffer實例,表示一塊16b的內存區。同時創建了兩個typed array,分別是32位和16位的。區別在于使用32位的訪問buffer時,會把buffer(16b)以32位為單位劃分為4個元素,讀寫都是以32位為單位進行的。16位的進行訪問時,會把buffer(16b)以16位為單位劃分為8個元素,每次讀寫都是16位。
第一個循環中,我們使用int32View向buffer中的4個元素中分別寫入了0,2,4,6 4個整數。
很顯然console中的結果是0,2,4,6。
第二個循環中,我們使用int16View以16位的格式讀取同一塊內存,可以想象原來的4個元素變成了8個元素,因此讀出的時候也會將原來的32位元素拆分為2個16位元素。因此console中的結果是0,0,2,0,4,0,6,0。
有同學可能對輸出的順序不理解,覺得為什么不是0,0,0,2,0,4,0,6呢。這里稍微解釋一下。
原因是默認情況下typed array 讀取數據的時候都是以小端模式來返回的。
所謂的小端模式(Little-endian),是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低,和我們的邏輯方法一致。
上例在小端模式下的存儲形式,每個框框表示16位。小端模式下數據的位權和地址的順序是一致的,從小到大排列。
總結typed array提供了一組讀取不同字長的類數組對象如,int8Array,int16Array,int64Array來實現對內存的操作。typed array的底層實現是基于ArrayBuffer和DataView實現的,對內存的分配和內存的讀取做了很好的分層設計。使用typed array使js向C語言等具備了操作二進制數據的能力。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90116.html
摘要:類型化數組也是中新引入的。用一句話解釋類型化數組就是它是操作二進制數據的接口。類型化數組類型化數組的應用二進制數據的接口主要應用于文件,在中涉及文件處理的幾乎都可以應用,主要是,,。 類型化數組(Typed Array)也是HTML5中新引入的API。用一句話解釋類型化數組就是:它是JS操作二進制數據的接口。 眾所周知,直接操作二進制數據可以使程序更為高效, 盡管JS對常規數組做了很多...
摘要:閉包的形成與變量的作用域以及變量的生存周期密切相關。現在我們把變量用閉包封閉起來,便能解決請求丟失的問題二高階函數高階函數是指至少滿足下列條件之一的函數。回調函數在異步請求的應用中,回調函數的使用非常頻繁。 一、閉包 對于 JavaScript 程序員來說,閉包(closure)是一個難懂又必須征服的概念。閉包的形成與變量的作用域以及變量的生存周期密切相關。下面我們先簡單了解這兩個知識...
摘要:調用函數,判斷返回的類型字符串,就知道是什么數據類型了判斷是否為瀏覽器的對象要為對象首先要滿足的條件是不能為或者,并且為自身的引用。必須存在中必須存在屬性返回的值調用函數,返回的數據類型。 數組方法 定義 var emptyArray = [] concat = emptyArray.concat filter = emptyArray.filter slice...
摘要:只要輸入的值不變,每次輸出都是一樣的值。指定位置元素運算操作如可用以下方式代替主要是生成中最核心的對象。描述發生了什么,是響應并對進行更新。生成的對象包含個方法,分別為,和。按照約定,具有字段來表示它的類型。 前言: 一開始接觸redux的時候最令我記住的一句話是:You Might Not Need Redux(那我還寫這篇文章干嘛?手動滑稽) 回歸正題,本文主要是圍繞redux...
閱讀 881·2023-04-26 03:03
閱讀 2206·2021-10-12 10:12
閱讀 1201·2021-09-24 09:48
閱讀 1645·2021-09-22 15:25
閱讀 3332·2021-09-22 15:15
閱讀 914·2019-08-29 16:21
閱讀 1064·2019-08-28 18:00
閱讀 3423·2019-08-26 13:44