位域 内存 字节序_JS操作内存?二进制数组了解一下
二進制數組的由來
主要是為了提高瀏覽器與顯卡之間的通信效率,由二進制數據代替傳統的文本。
二進制數組主要有三個對象:
- ArrayBuffer
- TypedArray
- DataView
ArrayBuffer對象
ArrayBuffer是一個構造函數,參數是一個數字,代表索取多少個字節的內存。例如:
var buffer = new ArrayBuffer(12);代表生成12個字節的內存區域。
注意:ArrayBuffer對象本身并不能直接對生成的內存區域進行讀寫(除了slice方法),需要借助視圖TypedArray和DataView來對其進行讀寫。
三個方法:
- 實例方法byteLength,返回生成內存的字節大小
- 實例方法slice,這個方法和數組類似,就是生成一段新的內存,并填充拷貝的內容
- 靜態方法isView,是否是視圖
demo1
TypedArray的用法
這種類型的視圖總共有9種構造函數:
- Int8Array 8位 有符號 一個字節 整數
- Uint8Array 8位 無符號 一個字節 整數
- Uint8ClampedArray 8位 無符號 一個字節 整數
- Int16Array 16位 有符號 兩個字節 整數
- Uint16Array 16位 無符號 兩個字節 整數
- Int32Array 32位 有符號 四個字節 整數
- Uint32Array 32位 無符號 四個字節 整數
- Float32Array 32位 四個字節 浮點數
- Float64Array 64位 八個字節 浮點數
用法1:
new TypedArray(buf, start, length)
- buf ArrayBuffer對象
- start開始的位置,默認是0
- length 字節的長度 相對于這種數據類型的長度
用法2:
new TypedArray(length)
直接傳入一個長度,生成一段內存區域
用法3:
new TypedArray(typedArray對象)
demo2
demo2中x和y視圖并沒有共享內存,如果想共享視圖可以這樣(傳入實例的buffer屬性):
demo3
用法4:
new TypedArray(普通的數組)
demo4
demo4中操作typedArray不會使aa發生變化,說明它們沒有共用同一段內存。
TypedArray的數值
二進制數組采用小端字節序,數組前面的元素的位相對較低,越往后越高,比如demo5中32這個元素就沒有后面0的元素位高,轉化成16進制應該是0x0000000000000020,如果采用16位或者32位視圖,再對應將其劃分。
demo5
小端字節序:低位在前,高位在后;
大端字節序:高位在前,低位在后;
TypedArray的數值溢出
什么是溢出呢?看下圖:
demo6
我們創建了一個Uint8Array視圖,它每一個元素的最大值是255(8位),最小值是0,當給定的數值不在這個區間內時,就會發生溢出!從demo6中我們給第一個元素賦值5000,但顯示的卻是136,這種現象就叫做溢出。
那么溢出的規則是什么?經過我的摸索得出了幾條規律!
無符號(先利用Uint8Array說明)
Uint8Array最大值255(max),最小值0(min),區間長度256(L),給其一個元素賦值m,最終顯示的值是n(例子見demo7)
//無符號最小值都是0if(m >= min){ //正向溢出 n = m%L } if (m < min) { //負向溢出,m是負數 n = L + m%L}demo7
有符合(先利用Int8Array說明)
Int8Array最大值127(max),最小值-128(min),區間長度256(L),給其一個元素賦值m,最終顯示的值是n(例子見demo8)
余數y = m%L//正向溢出(m是正數)if (y <= max) { n = y} if (y > max) { n = y - L}//負向溢出(此時y,min都是負數)if (y >= min) { n = y}if (y < min) { n = L + y}demo8
DataView對象
DataView對象和TypedArray對象最大的區別是可以自定義大端字節序還是小端字節序!
用法:
var buf = new ArrayBuffer(n);var dv = new DataView(buf, 字節起始位置, 長度);//查看demo6demo9
8個get方法:
- getInt8:讀取1個字節,返回一個8位整數。
- getUint8:讀取1個字節,返回一個無符號的8位整數。
- getInt16:讀取2個字節,返回一個16位整數。
- getUint16:讀取2個字節,返回一個無符號的16位整數。
- getInt32:讀取4個字節,返回一個32位整數。
- getUint32:讀取4個字節,返回一個無符號的32位整數。
- getFloat32:讀取4個字節,返回一個32位浮點數。
- getFloat64:讀取8個字節,返回一個64位浮點數。
//使用樣例dv.getXX(第幾個字節,大端字節序(false)/小端字節序(true))8個set方法:
- setInt8:寫入1個字節的8位整數。
- setUint8:寫入1個字節的8位無符號整數。
- setInt16:寫入2個字節的16位整數。
- setUint16:寫入2個字節的16位無符號整數。
- setInt32:寫入4個字節的32位整數。
- setUint32:寫入4個字節的32位無符號整數。
- setFloat32:寫入4個字節的32位浮點數。
- setFloat64:寫入8個字節的64位浮點數。
//使用樣例dv.setXX(第幾個字節,數據, 大端字節序(false)/小端字節序(true))總結
其實二進制數組在平時工作中并不常用,甚至不常見,不過還是有必要了解一下的!因為它是buffer的基礎,所以在研究buffer之前先了解一下!因為根據我的測試,自己摸索出了一個通用的規則,幫助大家理解,大家也可以幫我驗證,大家有想法的也可以留言給我補充!
喜歡我的文章就關注我吧,有問題可以發表評論,我們一起學習,共同成長!
總結
以上是生活随笔為你收集整理的位域 内存 字节序_JS操作内存?二进制数组了解一下的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 就这样结束了一切?
- 下一篇: 表格下划线怎么加粗_这招高!Excel签