ArrayBuffer

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

表示一个通用的固定长的的二进制缓冲区; 是一个字节数组

不能直接操作 需要 类型数组对象(TypedArray) 或 DataView 对象来操作

.slice 方法

类型数组对象

类型数组对象(TypedArray) : Int8Array Uint8Array(将每个字节视为一个单位),Uint16Array,Uint32Array

数组的方法都可以用

// 参数为数组长度,数组每一个值是 8位 // Uint16Array  数组每一个值是 16位
// 第二个参数表示偏移量(以字节为单位),第三个参数表示包含的元素个数
const typedArray1 = new Uint8Array(1, 0, 1) 
typedArray1[0] = 32; // 如果赋值 0xaa 16进制  会被转为10进制 170
typedArray1[0] = 256; // 会返回 0 因为 八位最大为 256,超出只保留后八位
console.log(typedArray1);
const typedArray2 = new Uint8Array(typedArray1.buffer) // 可以以现有实例创建,这里是开辟新内存 拷贝值; .buffer 一个已经存在的 arraybuffer
// const typedArray3 = new Uint8Array(typedArray1) // 这里用的同一个 buffer 所以 2和3 的实例值会相互影响
typedArray2[1] = 255
console.log(typedArray2);

const typedArray1 = new Uint8Array([21,31]) // 可以传数组,相当于 传入了长度和对每一位进行了赋值 

实际应用

ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
    const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
    }
    )
    return hexArr.join('')
}
16进度字符串转ArrayBuffer
function hexToArrayBuffer(str) {
    var pairs = str.match(/[\dA-F]{2}/gi);
    var integers = pairs.map(function(s) {
        return parseInt(s, 16);
    });
    var array = new Uint8Array(integers);
    return array.buffer;
}
// 参考 https://github.com/mattdesl/number-util
// IEEE 754浮点标准,并且根据标准,返回与表示整数位表示形式的给定参数相对应的float值
function intBitsToFloat(i) {
    var i32 = new Int32Array(1);
    i32[0] = i;
    var f32 = new Float32Array(i32.buffer);
    return f32[0];
};

function floatToIntBits(f) {
    var f32 = new Float32Array(1);
    f32[0] = f
    var i32 = new Int32Array(f32.buffer)
    return i32[0];
};

function intToFloatColor(value) {
	return intBitsToFloat( value & 0xfeffffff );
};

// 返回 rgba 的 Float32 
function colorToFloat(r, g, b, a) {
	var bits = (a << 24 | b << 16 | g << 8 | r);
	return intToFloatColor(bits);
};

/* 判断是否是 2^n 值 */
function isPowerOfTwo(n) {
	return (n & (n - 1)) === 0;
};

/* 指定一个数 n 返回比 n 大的第一个 2^n 数;比如输入8返回16;输入9返回16 */
function nextPowerOfTwo(n) {
	n--;
	n |= n >> 1;
	n |= n >> 2;
	n |= n >> 4;
	n |= n >> 8;
	n |= n >> 16;
	return n+1;
};

/* 将获取到的16进制字符串转为浮点数 */
function hexCharToFloat(hexString) {
    const ia = new Int8Array(4)
    // 这里没有用 hexString  直接固定了
    ia[0] = '0x41'
    ia[1] = '0x83'
    ia[2] = '0x99'
    ia[3] = '0x9a'

    var n = 0;
    n = n | (ia[3] & 0xff) << 0;
    n = n | (ia[2] & 0xff) << 8;
    n = n | (ia[1] & 0xff) << 16;
    n = n | (ia[0] & 0xff) << 24;

    function intBitsToFloat(i) {
        var i32 = new Int32Array(1);
        i32[0] = i;
        var f32 = new Float32Array(i32.buffer);
        return f32[0];
    };

    console.log(intBitsToFloat(n))
}

DataView

const arrayBuffer = new ArrayBuffer(2) // 参数为数组长度,单位为字节
// 返回 指定长度,内容初始化为0 的对象

new DataView(arrayBuffer, 起始位置, 长度); // 类似指定要获取buffer中的哪一段
// 返回 一个表示指定数据缓存区的新DataView 对象

const arrayBuffer = new ArrayBuffer(2) // 参数为长度,单位为字节
var view   = new DataView(arrayBuffer);
view.setUint16(0, 32896) // (1000 0000 1000 0000) uint 无符号整型
console.log(view.getUint16(0)); // 32896
console.log(view.getUint8(0)); // (1000 0000) 2^7 => 128

const arrayBuffer1 = new ArrayBuffer(2)
var view1   = new DataView(arrayBuffer1);
view1.setInt16(0, 49216) // (1100 0000 0100 0000) 开始字节的第一位如果是1表示负数
// (100 0000 0100 0000) 取反 (011 1111 1011 1111) 再加一 再加上符号 => -16320 负数的表示:正数取反加一 
console.log(view1.getInt16(0)); // -16320
console.log(view1.getInt8(1)); //  // (0100 0000) => 64

Last Updated:
Contributors: Warren