摘要:原始緩沖區(qū)的創(chuàng)建通過這個構(gòu)造函數(shù)可以創(chuàng)建一個原始緩沖區(qū)從控制臺可以看到實例擁有一個的屬性,用于獲取的,一個只有以及支持的方法,用于對長度進行截取操作。所有數(shù)組類型的長度均固定。
本文同步自我的博客園:http://www.cnblogs.com/hustskyking/
相信每一個 javascript 學(xué)習(xí)者,都會去了解 JS 的各種基本數(shù)據(jù)類型,數(shù)組就是數(shù)據(jù)的組合,這是一個很基本也十分簡單的概念,他的內(nèi)容沒多少,學(xué)好它也不是件難事情。但是本文著重要介紹的并不是我們往常看到的 Array,而是 ArrayBuffer。
我寫的很多東西都是因為要完成某些特定的功能而刻意總結(jié)的,可以算是備忘,本文也是如此!前段時間一直在研究 Web Audio API 以及語音通信相關(guān)的知識,內(nèi)容側(cè)重于音頻流在 AudioContext 各個節(jié)點之間的流動情況,而現(xiàn)在要摸清楚音頻到流底是個什么樣的數(shù)據(jù)格式,所以對 ArrayBuffer 的研究就顯得格外重要了。
一、Array 在內(nèi)存中的堆棧模型 1. Array 的獲取Javascript 中如何產(chǎn)生 Array:
[element0, element1, ..., elementN] new Array(element0, element1, ..., elementN) new Array(arrayLength)
直接定義,或者通過構(gòu)造函數(shù)創(chuàng)建一個 Array,當(dāng)然也可以使用其他的手段:
"array".split(""); "array".match(/a|r/g);
等等,方式有很多。但是 Array 內(nèi)部是個什么樣的結(jié)構(gòu),恐怕很多人還不是很清楚。
2. 堆棧模型在數(shù)組中我們可以放很多不同數(shù)據(jù)類型的數(shù)據(jù),如:
var arr = [21, "李靖", new Date(), function(){}, , null];
上面這個數(shù)組中一次放入了 數(shù)字、字符串、對象、函數(shù)、undefined 和 null,對于上面的數(shù)據(jù)接口我們可以具象的描述下:
棧 +---------+ 堆 | 21 | +-------------------+ +---------+ | | | "李靖" | | | +---------+ | +--------+ | | [refer] |----------->| Object | | +---------+ | +--------+ | | [refer] |----------------->+--------+ | +---------+ | |function| | |undefined| | +--------+ | +---------+ | | | null | +-------------------+ +---------+ Created By Barret Lee
JavaScript 的數(shù)據(jù)類型分為兩種,一種是值類型,一種是引用類型,常見的引用類型有 Object 和 Array,數(shù)組的儲存模型中,如果是諸如 Number、String 之類的值類型數(shù)據(jù)會被直接壓入棧中,而引用類型只會壓入對該值的一個索引,用 C 語言的概念來解釋就是只保存了數(shù)據(jù)的指針,這些數(shù)據(jù)是儲存在堆中的某塊區(qū)間中。棧堆并不是獨立的,棧也可以在堆中存放。
好了,對 Array 的說明就到這里,下面具體說說 ArrayBuffer 的相關(guān)知識。
二、ArrayBufferweb 是個啥玩意兒,web 要討論的最基本問題是什么?我覺得有兩點,一個是數(shù)據(jù),一個是數(shù)據(jù)傳輸,至于數(shù)據(jù)的展示,紛繁復(fù)雜,這個應(yīng)該是 web 上層的東西。而本文要討論的 ArrayBuffer 就是最基礎(chǔ)的數(shù)據(jù)類型,甚至不能稱之為數(shù)據(jù)類型,它是一個數(shù)據(jù)容易,需要通過其他方式來讀寫。
官方點的定義:
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 ArrayBufferView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.
表示二進制數(shù)據(jù)的原始緩沖區(qū),該緩沖區(qū)用于存儲各種類型化數(shù)組的數(shù)據(jù)。 無法直接讀取或?qū)懭?ArrayBuffer,但可根據(jù)需要將其傳遞到類型化數(shù)組或 DataView 對象 來解釋原始緩沖區(qū)。
他是一個二進制數(shù)據(jù)的原始緩沖區(qū),雖然 JavaScript 是弱類型語言,但是他本身是對數(shù)據(jù)的類型和大小都有限制的,我們需要通過某種數(shù)據(jù)結(jié)構(gòu)將緩沖區(qū)的內(nèi)容有序的讀取出來(寫進去)。
1. 原始緩沖區(qū)的創(chuàng)建通過 ArrayBuffer 這個構(gòu)造函數(shù)可以創(chuàng)建一個原始緩沖區(qū):
var buffer = new ArrayBuffer(30);
從 chrome 控制臺可以看到:
[![arrayBuffer]({{ site.repo }}/images/blog-article-images/blog/audio/arraybuffer.jpg)]({{ site.repo }}/images/blog-article-images/blog/audio/arraybuffer.jpg)
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]);2. 類型化數(shù)組
類型化數(shù)組類型表示可編制索引和操縱的 ArrayBuffer 對象 的各種視圖。 所有數(shù)組類型的長度均固定。
名稱 | 大?。ㄒ宰止?jié)為單位) | 描述 |
---|---|---|
Int8Array | 1 | 8 位二補碼有符號整數(shù) |
Uint8Array | 1 | 8 位無符號整數(shù) |
Int16Array | 2 | 16 位二補碼有符號整數(shù) |
Uint16Array | 2 | 16 位無符號整數(shù) |
Int32Array | 4 | 32 位二補碼有符號整數(shù) |
Uint32Array | 4 | 32 位無符號整數(shù) |
Float32Array | 4 | 32 位 IEEE 浮點數(shù) |
Float64Array | 8 | 64 位 IEEE 浮點數(shù) |
Int 就是整型,Uint 為無符號整形,F(xiàn)loat 為浮點型,這些是 C 語言中的基本概念,我就不具體解釋了。由于這些視圖化結(jié)構(gòu)都是大同小異,本文只對 Float32Array 類型作說明,讀者可以舉一反三。
Float32Array 跟 Array 是十分類似的,只不過他每一個元素都是都是一個 32位(4字節(jié)) 的浮點型數(shù)據(jù)。Float32Array 一旦創(chuàng)建其大小不能再修改。
我們可以直接創(chuàng)建一個 Float32Array:
var x = new Float32Array(2); x[0] = 17; console.log(x[0]); // 17 console.log(x[1]); // 0 console.log(x.length); // 2
需要有這么一個概念,他依然是一個數(shù)組,只不過該數(shù)組中的每個元素都是 Float 32 位的數(shù)據(jù)類型,再如:
var x = new Float32Array([17, -45.3]); console.log(x[0]); // 17 console.log(x[1]); // -45.29999923706055 console.log(x.length); // 2
我們把一個數(shù)組的值直接賦給了 x 這個 Float32Array 對象,那么在儲存之前會將它轉(zhuǎn)換成一個 32位浮點數(shù)。
由于該類數(shù)組的每個元素都是同一類型,所以在堆棧模型中,他們?nèi)繒粔喝氲綏V?,因此類型化?shù)組都是值類型,他并不是引用類型!這個要引起注意,從下面的例子中也可以反映出來:
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 的值復(fù)制給 y,修改 x[0], y[0] 并沒有變化。
除了上面的方式,我們還可以通過其他方式來創(chuàng)建一個類型化數(shù)組:
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
看了上面的圖解還有疑問么?我覺得我不用繼續(xù)解釋了??梢园?ArrayBuffer 的單位看成 1,而 Float32Array 的單位是 4.
3. DataView對象DataView 對象對數(shù)據(jù)的操作更加細(xì)致,不過我覺得沒啥意思,上面提到的各種類型化數(shù)組已經(jīng)可以基本滿足應(yīng)用了,所以這里就一筆帶過,一個簡單的示例:
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,作詳細(xì)了解。
三、XHR2 中的 ArrayBufferArrayBuffer 的應(yīng)用特別廣泛,無論是 WebSocket、WebAudio 還是 Ajax等等,前端方面只要是處理大數(shù)據(jù)或者想提高數(shù)據(jù)處理性能,那一定是少不了 ArrayBuffer 。
XHR2 并不是什么新東西,可能你用到了相關(guān)的特性,卻不知這就是 XHR2 的內(nèi)容。最主要的一個東西就是 xhr.responseType,他的作用是設(shè)置響應(yīng)的數(shù)據(jù)格式,可選參數(shù)有:"text"、"arraybuffer"、"blob"或"document"。請注意,設(shè)置(或忽略)xhr.responseType = "" 會默認(rèn)將響應(yīng)設(shè)為"text"。這里存在一個這樣的對應(yīng)關(guān)系:
請求 響應(yīng) 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 中設(shè)置了屬性為 arraybuffer,那么在拿到的數(shù)據(jù)中就可以用類型化數(shù)組來接受啦!
四、小結(jié)本文主要介紹了 Array 在堆棧模型中的存放方式,也詳細(xì)描述了 ArrayBuffer 這個原始緩沖區(qū)的二進制數(shù)據(jù)類型,在 web 開發(fā)中,數(shù)據(jù)以及數(shù)據(jù)的儲存是一個重要的部分,希望引起注意!
本文敘述上可能存在錯誤,請多多斧正!
五、參考資料http://www.javascripture.com/ArrayBuffer
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array MDN Array
http://www.html5rocks.com/zh/tutorials/file/xhr2/ html5rocks
http://technet.microsoft.com/zh-cn/ie/br212485 MSDN
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78026.html
摘要:已經(jīng)逐漸替代被全世界的開發(fā)者廣泛使用。函數(shù)將一個對象轉(zhuǎn)換成文本化的。不能被文本化的屬性會被忽略。和例外情況在數(shù)組中,不可被的元素用填充。自從年雙十一正式上線,累計處理了億錯誤事件,得到了金山軟件等眾多知名用戶的認(rèn)可。 譯者按: 老司機們,你知道JSON.stringify還有第二個和第三個可選參數(shù)嗎?它們是什么呢? 原文: What you didn’t know about JSO...
摘要:但好在還給我們提供了一個方法,每一個對象都有這樣一個方法,專門用來判斷某個屬性是否是該對象的私有屬性。如果你想要用對象字面形式,你只能在創(chuàng)建對象時定義訪問器屬性。在中,我們使用凍結(jié)一個對象,并且使用來判斷一個對象是否被凍結(jié)。 說完了對象那些不常用的冷知識,是時候來看看JavaScript中對象屬性有哪些有意思的東西了。 不出你所料,對象屬性自然也有其相應(yīng)的特征屬性,但是這個話題有點復(fù)雜...
前言 console.log 可以是在日常 Web 開發(fā)中最常用的方法了,但是你應(yīng)該知道 console 比你想象的強。 1.凡人視角 打印字符串 代碼: console.log(I am a 凡人); 打印提示消息 代碼: console.info(Yes, you are a 凡人); 打印警告消息 代碼: console.warn(凡人你居然敢窺視我); 打印錯誤消息 代碼: console...
前言 console.log 可以是在日常 Web 開發(fā)中最常用的方法了,但是你應(yīng)該知道 console 比你想象的強。 1.凡人視角 打印字符串 代碼: console.log(I am a 凡人); 打印提示消息 代碼: console.info(Yes, you are a 凡人); 打印警告消息 代碼: console.warn(凡人你居然敢窺視我); 打印錯誤消息 代碼: console...
閱讀 2236·2021-11-24 11:15
閱讀 3079·2021-11-24 10:46
閱讀 1378·2021-11-24 09:39
閱讀 3924·2021-08-18 10:21
閱讀 1478·2019-08-30 15:53
閱讀 1395·2019-08-30 11:19
閱讀 3319·2019-08-29 18:42
閱讀 2321·2019-08-29 16:58