前置知识: HTML5、CSS

JavaScript ArrayBuffer 与 TypedArray 语法速查手册

2 min入门

JavaScript ArrayBuffer 与 TypedArray 语法速查 的完整教学讲解。

ArrayBuffer 基础

基本写法:创建定长缓冲 new ArrayBuffer(<字节数>)

// 原始二进制数据,固定长度
const buf = new ArrayBuffer(16);
buf.byteLength; // 16
buf.detached;   // false(是否被转移)

基本写法:可扩容 ArrayBuffer(ES2024) new ArrayBuffer(<长度>, { maxByteLength: <最大> })

// 创建可调整大小的缓冲
const buf = new ArrayBuffer(8, { maxByteLength: 32 });
buf.resizable;        // true
buf.maxByteLength;    // 32
buf.resize(16);       // 扩容
buf.resize(4);        // 缩容

基本写法:transfer 转移所有权(ES2024) <buffer>.transfer([<新字节长度>])

// 转移后原 buffer 被分离不可用
const a = new ArrayBuffer(8);
const b = a.transfer();   // a.detached === true

TypedArray 类型

基本写法:创建各类定型数组 new <TypedArray>(<长度>)

// 常见类型
new Int8Array(4);        // 8 位有符号
new Uint8Array(4);       // 8 位无符号
new Uint8ClampedArray(4);// 钳制 0-255
new Int16Array(4);       // 16 位有符号
new Uint16Array(4);      // 16 位无符号
new Int32Array(4);       // 32 位有符号
new Uint32Array(4);      // 32 位无符号
new Float32Array(4);     // 32 位浮点
new Float64Array(4);     // 64 位浮点
new BigInt64Array(4n);   // 64 位大整数
new BigUint64Array(4n);  // 64 位无符号大整数
new Float16Array(4);     // 16 位浮点(ES2025)

基本写法:从数组或缓冲创建 new <TypedArray>(<可迭代>) | new <TypedArray>(<buffer>, [<偏移>], [<长度>])

// 从数组创建
const a = new Uint8Array([1, 2, 3]);
// 共享底层 ArrayBuffer
const buf = new ArrayBuffer(8);
const view = new Uint8Array(buf, 0, 4); // 偏移 0,长度 4

TypedArray 属性与操作

基本写法:底层视图属性 <view>.buffer | <view>.byteLength | <view>.byteOffset

// 访问底层 buffer 与位置
const v = new Int32Array(buf, 4, 2);
v.buffer;      // 底层 ArrayBuffer
v.byteLength;  // 占用字节数
v.byteOffset;  // 在 buffer 中的偏移
v.length;      // 元素个数

基本写法:set 复制数据 <view>.set(<数组或定型数组>, [<偏移>])

// 批量写入
const v = new Uint8Array(8);
v.set([10, 20, 30], 2); // 从偏移 2 开始写入

基本写法:subarray 共享视图 <view>.subarray([<开始>, <结束>])

// 返回共享内存的子视图
const v = new Uint8Array([1, 2, 3, 4]);
const sub = v.subarray(1, 3); // [2, 3],修改 sub 影响 v

DataView 视图

基本写法:创建 DataView new DataView(<buffer>, [<偏移>], [<长度>])

// 可混用大小端读写不同类型
const dv = new DataView(new ArrayBuffer(8));
dv.setInt8(0, 127);
dv.getInt8(0);    // 127

基本写法:指定字节序读写 <dv>.setInt32(<偏移>, <值>, [<小端>])

// 第三个参数 true 表示小端序
dv.setInt32(0, 0x12345678, true);
dv.getInt32(0, true);     // 305419896
dv.getFloat64(0, true);   // 读取 64 位浮点

SharedArrayBuffer 与 Atomics

基本写法:共享缓冲 new SharedArrayBuffer(<字节数>)

// 可跨线程共享(Worker)
const sab = new SharedArrayBuffer(16);
const view = new Int32Array(sab);

基本写法:原子操作 Atomics.add(<view>, <索引>, <值>)

// 原子读改写,避免竞态
const view = new Int32Array(sab);
Atomics.store(view, 0, 10);
Atomics.add(view, 0, 5);     // 返回旧值 10
Atomics.load(view, 0);       // 15
Atomics.compareExchange(view, 0, 15, 20); // 期望 15 才写 20

基本写法:等待与通知 Atomics.wait(<view>, <索引>, <期望值>) | Atomics.notify(<view>, <索引>, [<数量>])

// 线程间同步
Atomics.wait(view, 0, 0);        // 阻塞直到被通知
Atomics.notify(view, 0, 1);      // 唤醒 1 个等待者
Atomics.waitAsync(view, 0, 0);   // 异步等待(ES2024)

编码转换

基本写法:字符串与 TypedArray 互转 new TextEncoder().encode(<字符串>)

// UTF-8 编解码
const enc = new TextEncoder();
const bytes = enc.encode("中文"); // Uint8Array
const dec = new TextDecoder("utf-8");
dec.decode(bytes); // "中文"

字节序判断

基本写法:判断大小端 new Uint8Array(new Uint32Array([1]).buffer)

// 小端序返回 [1,0,0,0],大端序返回 [0,0,0,1]
const le = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
console.log(le ? "little-endian" : "big-endian");

核心知识点

一句话记住二进制:ArrayBuffer 是原始字节块,TypedArray 是带类型的视图,DataView 是灵活读写;二进制数据用 Uint8Array 最常用。

  • ArrayBuffer:固定长度的二进制缓冲区;
  • TypedArray:Uint8Array/Int32Array/Float64Array 等类型化视图;
  • DataView:按任意偏移与字节序读写;
  • Blob/File:二进制对象,用于文件与上传;
  • 与字符串互转:TextEncoder/TextDecoder;
  • 场景:文件解析、图像处理、网络协议。

动手试试

  1. 创建 16 字节的 ArrayBuffer,用 Uint8Array 写入并读取;
  2. 用 TextEncoder 把字符串转成字节,再转回;
  3. 读取一个文件的 arrayBuffer();
  4. 进阶挑战:解析一个简单的二进制文件头。

注意事项与改进建议

问题点说明改进方案
越界访问读取到 undefined 或抛错检查长度与偏移
字节序混淆多字节数值错乱DataView 显式指定 littleEndian
大缓冲区拷贝性能差使用 transfer 转移所有权

扩展学习

  • 存储:javascript/470-IndexedDBADatabaseInYourBrowser;
  • 性能:javascript/500-DebugPerformanceOptimization;
  • 文件:html5/240-HTML5OfflineStorageWebAPI。