typedarray 与 arraybuffer 是否有效取决于其是否真实指向可读写的连续二进制内存:需验证 arraybuffer.bytelength > 0 且未 detached,typedarray.view.buffer.bytelength > 0 且视图范围合法,内存布局物理连续,并通过跨视图读写、subarray 零拷贝等行为佐证。

检测 TypedArray 与 ArrayBuffer 是否有效,核心是验证它们是否真实指向一段可读写的连续二进制内存,而非空、 detached 或中间态对象。关键不在于“能不能用”,而在于“内存是否就位、视图是否合法、数据是否可控”。
检查 ArrayBuffer 是否有效
一个有效的 ArrayBuffer 必须有非零长度且未被转移或释放:
- 确认 byteLength > 0:若
buffer.byteLength === 0,说明它已被 transfer 到 Worker 或显式释放,不可再访问 - 避免仅靠
buffer instanceof ArrayBuffer:它只判构造器,无法识别 detached 状态;必须结合 byteLength 判断 - 用
ArrayBuffer.isView(view)反向验证:若传入的是 ArrayBuffer 本身,返回false;这是区分 buffer 和 view 的安全方式
验证 TypedArray 视图是否绑定有效 buffer
TypedArray 实例可能已失去底层内存(比如 transfer 后),需主动检查其 buffer 状态:
- 检查 view.buffer.byteLength > 0:这是最直接的 detached 判定依据;为 0 即失效
- 核对 view.byteLength === view.buffer.byteLength(当无偏移时)或更通用的
view.byteOffset + view.byteLength :确保视图范围没越界 - 避免依赖
view.length单独判断:长度合法不代表 buffer 有效;new Uint8Array(new ArrayBuffer(0))的 length 是 0,但 buffer 已无效
确认内存布局真实连续(非逻辑连续)
普通数组看似连续,实则每个元素都是独立 JS 对象;TypedArray 的优势依赖物理连续性:
- 比对
view.length * view.BYTES_PER_ELEMENT === view.byteLength:不等说明存在 padding 或构造异常(如从普通数组创建) - 尝试跨视图读写:用
new Int32Array(view.buffer)修改某位置,再用原Uint8Array检查对应字节是否同步变化(注意小端/大端);若不同步,说明 buffer 不一致或被复制 - 拒绝
Uint8Array.from([1,2,3])类构造:它先建普通数组再拷贝,破坏连续性;应优先用new Uint8Array(3)或new Uint8Array(arrayBuffer)
观察运行时行为佐证有效性
内存有效性会在实际使用中留下痕迹,可通过轻量操作验证:
- 大量写入时监控 V8 堆内存:TypedArray 元素不进 JS 堆,Heap Used 几乎不变,而 ArrayBuffer 占用持续存在
- 调用
subarray()后检查subview.buffer === original.buffer:为 true 才说明是零拷贝切片;若为 false,说明内部发生了复制 - 网络或文件读取后直接用
res.arrayBuffer()或FileReader.readAsArrayBuffer():若中途转成字符串/base64,后续 TypedArray 就只是副本,不再反映原始内存











