相信每個javascript 學習者,都會去了解JS 的各種基本資料類型,陣列就是資料的組合,這是一個很基本也十分簡單的概念,他的內容沒多少,學好它也不是件難事情。但本文著重要介紹的並不是我們平常看到的 Array,而是 ArrayBuffer。
我寫的很多東西都是因為要完成某些特定的功能而刻意總結的,可以算是備忘,本文也是如此!前段時間一直在研究Web Audio API 以及語音通訊相關的知識,內容著重於音訊串流在AudioContext 各個節點之間的流動情況,而現在要摸清楚音訊到流底是個什麼樣的資料格式,所以對ArrayBuffer 的研究就顯得格外重要了。
Array 在記憶體中的堆疊模型
Array 的取得
Javascript 中如何產生 Array:
[element0, element1, ..., elementN]
new Array(element0, element1, ..., elementN)
new Array(arrayLength)
直接定義,或透過建構函式創建一個 Array,當然也可以使用其他的手段:
"array".split("");
"array".match(/a|r/g);
等等,方式有很多。但是 Array 內部是個什麼樣的結構,恐怕很多人還不太清楚。
堆疊模型
在數組中我們可以放很多不同數據類型的數據,如:
var arr = [21, "李靖", new Date(), function(){}, , null];
上面這個陣列中一次放入了 數字、字串、物件、函數、undefined 和 null,對於上面的資料介面我們可以具象的描述下:
堆疊
--------- 堆疊者
| 21 | -------------------
--------- | |
| "李靖" | | |
--------- | -------- |
| [refer] |----------->| Object | |
--------- | -------- |
| [refer] |-----------------> -------- |
--------- | |function| |
|undefined| | -------- |
--------- | |
| null | ------------------
--------- Created By Barret Lee
JavaScript 的資料型別分為兩種,一種是值型,一種是參考型別,常見的參考型別有Object 和Array,數組的儲存模型中,如果是諸如Number、String 之類的值類型資料會直接壓入堆疊中,而引用類型只會壓入對該值的索引,用C 語言的概念來解釋就是只保存了資料的指針,這些資料是儲存在堆中的某塊區間中。棧堆並不是獨立的,棧也可以在堆中存放。
好了,對 Array 的說明就到這裡,下面具體說說 ArrayBuffer 的相關知識。
ArrayBuffer
web 是個啥玩意兒,web 要討論的最基本問題是什麼?我覺得有兩點,一個是數據,一個是數據傳輸,至於數據的展示,紛繁複雜,這個應該是 web 上層的東西。而本文要討論的 ArrayBuffer 就是最基礎的資料類型,甚至不能稱之為資料類型,它是一個資料容易,需要透過其他方式來讀寫。
官方要點的定義:
The ArrayBuffer is a data type that is used to represent a generic, fixed-length binary data buffer. You can't directly manipulate the contents of an ArrayBuffer; instead, you create an ArificBuffer View. format, and use that to read and write the contents of the buffer.
表示二進位資料的原始緩衝區,該緩衝區用於儲存各種類型化數組的資料。 無法直接讀取或寫入 ArrayBuffer,但可根據需要將其傳遞到類型化陣列或 DataView 物件 來解釋原始緩衝區。
他是一個二進位資料的原始緩衝區,雖然JavaScript 是弱類型語言,但是他本身是對資料的類型和大小都有限制的,我們需要透過某種資料結構將緩衝區的內容有序的讀取出來(寫進去)。
原始緩衝區的建立
透過 ArrayBuffer 這個建構子可以建立一個原始緩衝區:
var buffer = new ArrayBuffer(30);
從 chrome 控制台可以看到:
buffer 實例擁有一個 byteLength 的屬性,用於取得 buffer 的 size,一個只有 IE11 以及 ios6 支援的 slice 方法,用於對 buffer 長度進行截取操作。
ArrayBuffer slice(
unsigned long begin
unsigned long end Optional
);
可以測試這個 DEMO:
var buffer = new ArrayBuffer(12);
var x = new Int32Array(buffer);
x[1] = 1234;
var slice = buffer.slice(4);
var y = new Int32Array(slice);
console.log(x[1]);
console.log(y[0]);
x[1] = 6789;
console.log(x[1]);
console.log(y[0]);
資料化陣列
類型化陣列類型表示可編制索引和操縱的 ArrayBuffer 物件 的各種視圖。 所有數組類型的長度均固定。
名稱 大小(以位元組為單位) 描述
Int8Array 1 8 位元二補碼有符號整數
Uint8Array 1 8 位元無符號整數
Int16Array 2 16 位元二補碼有符號整數
Uint16Array 2 16 位元無符號整數
Int32Array 4 32 位元二補碼有符號整數
Uint32Array 4 32 位元無符號整數
Float32Array 4 32 位元 IEEE 浮點數
Float64Array 8 64 位元 IEEE 浮點數
Int 是整數型,Uint 為無符號整形,Float 為浮點型,這些是 C 語言中的基本概念,我就不具體解釋了。由於這些視圖化結構都是大同小異,本文只對 Float32Array 類型作說明,讀者可以舉一反三。
Float32Array 跟 Array 是十分類似的,只不過他每一個元素都是一個 32位元(4位元組) 的浮點型資料。 Float32Array 一旦創建其大小不能再修改。
我們可以直接建立一個 Float32Array:
var x = new Float32Array(2);
x[0] = 17;
console.log(x[0]); // 17
console.log(x[1]); // 0
console.log(x.length); // 2
需要有這麼一個概念,他依然是一個數組,只不過該數組中的每個元素都是 Float 32 位元的資料型別,再如:
var x = new Float32Array([17, -45.3]);
console.log(x[0]); // 17
console.log(x[1]); // -45.29999923706055
console.log(x.length); // 2
我們把一個陣列的值直接賦給了 x 這個 Float32Array 對象,那麼在儲存之前會將它轉換成一個 32位元浮點數。
由於該類別數組的每個元素都是同一型,所以在堆疊模型中,他們全部會被壓入到堆疊之中,因此資料化數組都是值類型,他並不是引用類型!這個要引起注意,從下面的例子也可以反映出來:
var x = new Float32Array([17, -45.3]);
var y = new Float32Array(x);
console.log(x[0]); // 17
console.log(x[1]); //-45.29999923706055
console.log(x.length); // 2
x[0] = -2;
console.log(y[0]); // 17, y的值沒變
將 x 的值複製給 y,修改 x[0], y[0] 並沒有改變。
除了上面的方式,我們還可以透過其他方式來建立一個資料化數組:
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
解釋下這裡為什麼回 7.
ArrayBuffer(12)
- - - - - - - - - - - - -
|0|1|2|3|4|5|6|7|8| | | | | |
- - - - - - - - - - - - -
/
x (Float32Array)
offset:0
byteLength:4
length:2
ArrayBuffer(12)
- - - - - - - - - - - - -
|0|1|2|3|4|5|6|7|8| | | | | |
- - - - - - - - - - - - -
/
y
Created By Barret Lee
看了上面的圖解還有疑問麼?我覺得我不用繼續解釋了。可以把 ArrayBuffer 的單位看成 1,而 Float32Array 的單位是 4.
DataView物件
DataView 物件對資料的操作更加細緻,不過我覺得沒啥意思,上面提到的各種資料化數組已經可以基本滿足應用了,所以這裡就一筆帶過,一個簡單的示例:
var buffer = new ArrayBuffer(12);
var x = new DataView(buffer, 0);
x.setInt8(0, 22);
x.setFloat32(1, Math.PI);
console.log(x.getInt8(0)); // 22
console.log(x.getFloat32(1)); // 3.1415927410125732
如果有興趣,可以移步http://www.javascripture.com/DataView,作詳細了解。
XHR2 中的 ArrayBuffer
ArrayBuffer 的應用特別廣泛,無論是 WebSocket、WebAudio 還是 Ajax等等,前端方面只要是處理大數據或想提高資料處理效能,那一定是少不了 ArrayBuffer 。
XHR2 並不是什麼新東西,可能你用到了相關的特性,卻不知這就是 XHR2 的內容。最主要的東西就是 xhr.responseType,他的作用是設定回應的資料格式,可選參數有:"text"、"arraybuffer"、"blob"或"document"。請注意,設定(或忽略)xhr.responseType = '' 會預設將回應設為"text"。這裡存在著一個這樣的對應關係:
請求 回應
text DOMString
arraybuffer ArrayBuffer
blob Blob
document Document
舉個栗子:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
// this.response == uInt8Array.buffer
var uInt8Array = new Uint8Array(this.response);
};
xhr.send();
我們在 xhr.responseType 中設定了屬性為 arraybuffer,那麼在拿到的資料中就可以用資料化陣列來接受啦!
小結
本文主要介紹了 Array 在堆疊模型中的存放方式,也詳細描述了 ArrayBuffer 這個原始緩衝區的二進位資料類型,在 web 開發中,資料以及資料的儲存是一個重要的部分,希望引起注意!
本文敘述上可能有錯誤,請多多斧正!

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

記事本++7.3.1
好用且免費的程式碼編輯器

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Atom編輯器mac版下載
最受歡迎的的開源編輯器