JavaScript ArrayBuffer 详解与使用完全指南

 更新时间:2025年08月28日 14:36:05   作者:二川bro  
ArrayBuffer是JavaScript中处理二进制数据的核心API,为开发者提供了直接操作内存的能力,本文将深入解析ArrayBuffer 的原理、使用场景,并通过代码案例展示其与常见数据结构的对比,感兴趣的朋友跟随小编一起看看吧

JavaScript ArrayBuffer 详解与使用指南

ArrayBuffer 是 JavaScript 中处理二进制数据的核心 API,为开发者提供了直接操作内存的能力。本文将深入解析 ArrayBuffer 的原理、使用场景,并通过代码案例展示其与常见数据结构的对比。

一、ArrayBuffer 基础概念

1. 什么是 ArrayBuffer?

ArrayBuffer 是一个表示通用、固定长度原始二进制数据缓冲区的对象。它:

  • 不能直接读写,需要通过视图(TypedArray 或 DataView)操作
  • 具有固定长度,创建后不可调整大小
  • 常用于处理文件、图像、网络协议等二进制数据

2. 核心特性对比

特性ArrayBuffer普通数组 (Array)
数据类型纯二进制数据任意 JavaScript 类型
操作方式必须通过视图直接通过索引访问
内存效率更高(直接内存操作)较低(包含类型信息)
可变长度❌ 固定大小✅ 动态调整

二、基本使用方法

1. 创建 ArrayBuffer

// 创建 16 字节的缓冲区
const buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); // 16

2. 使用视图操作数据

TypedArray 视图

// 创建 16 位无符号整数视图
const uint16View = new Uint16Array(buffer);
// 写入数据
uint16View[0] = 0x1234;
uint16View[1] = 0x5678;
// 读取数据
console.log(uint16View[0].toString(16)); // "1234"
console.log(uint16View[1].toString(16)); // "5678"

DataView 视图(更灵活)

const view = new DataView(buffer);
// 写入数据(指定字节序)
view.setUint16(0, 0x1234, false); // 大端序
view.setUint16(2, 0x5678, true);  // 小端序
// 读取数据
console.log(view.getUint16(0, false).toString(16)); // "1234"
console.log(view.getUint16(2, true).toString(16));  // "5678"

三、实际应用案例

1. 处理 RGB 图像数据

// 创建 3 像素的 RGB 缓冲区(每个像素 3 字节)
const rgbBuffer = new ArrayBuffer(9);
const rgbView = new Uint8Array(rgbBuffer);
// 填充像素数据(R,G,B 格式)
rgbView.set([255, 0, 0, 0, 255, 0, 0, 0, 255]); // 红、绿、蓝
// 读取第二个像素的绿色分量
console.log(rgbView[4]); // 255

2. 网络协议解析(以 TCP 头部为例)

// 模拟 20 字节的 TCP 头部
const tcpHeaderBuffer = new ArrayBuffer(20);
const tcpView = new DataView(tcpHeaderBuffer);
// 设置源端口(大端序)
tcpView.setUint16(0, 54321, false);
// 设置目的端口(小端序)
tcpView.setUint16(2, 80, true);
// 读取源端口
console.log(tcpView.getUint16(0, false)); // 54321

3. 与 Blob 结合处理文件

// 从文件创建 ArrayBuffer
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();
  reader.onload = (event) => {
    const buffer = event.target.result;
    const uint8View = new Uint8Array(buffer);
    // 读取文件前 4 字节
    const fileSignature = Array.from(uint8View.slice(0, 4))
      .map(b => b.toString(16).padStart(2, '0'))
      .join(' ');
    console.log('File signature:', fileSignature);
  };
  reader.readAsArrayBuffer(file);
});

四、性能对比与选择建议

1. 与普通数组性能对比

// 测试 100 万次数据操作
const arraySize = 1e6;
// 普通数组测试
console.time('Array');
const arr = new Array(arraySize);
for (let i = 0; i < arraySize; i++) {
  arr[i] = i % 256;
}
console.timeEnd('Array'); // 约 5-10ms
// ArrayBuffer 测试
console.time('ArrayBuffer');
const buffer = new ArrayBuffer(arraySize);
const typedArr = new Uint8Array(buffer);
for (let i = 0; i < arraySize; i++) {
  typedArr[i] = i % 256;
}
console.timeEnd('ArrayBuffer'); // 约 1-3ms

2. 选择建议

  • 使用 ArrayBuffer 当
    • 处理二进制数据(如图像、音频、网络协议)
    • 需要直接内存操作以提高性能
    • 与 WebAssembly 或 WebGL 交互
  • 使用普通数组当
    • 需要动态大小调整
    • 存储复杂数据结构
    • 不需要直接内存操作

五、高级技巧与注意事项

1. 缓冲区共享与切片

// 创建共享缓冲区
const sharedBuffer = new ArrayBuffer(16);
const view1 = new Uint32Array(sharedBuffer);
const view2 = new Uint8Array(sharedBuffer, 4, 8); // 从第4字节开始,长度8字节
view1[0] = 0x12345678;
console.log(view2[0].toString(16)); // "78" (小端序下的第一个字节)

2. 字节序处理

// 处理不同字节序的数据
function readInt32(buffer, offset, isLittleEndian) {
  const view = new DataView(buffer);
  return view.getInt32(offset, isLittleEndian);
}
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setInt32(0, 0x12345678, false); // 大端序写入
console.log(readInt32(buffer, 0, false).toString(16)); // "12345678"
console.log(readInt32(buffer, 0, true).toString(16));  // "78563412"

3. 安全注意事项

  • 始终检查缓冲区边界
  • 避免直接暴露缓冲区给不可信代码
  • 注意 Node.js 中 Buffer 与浏览器 ArrayBuffer 的差异

六、总结

ArrayBuffer 是 JavaScript 处理二进制数据的基石,通过:

  1. 固定长度的原始二进制存储
  2. 通过视图提供类型化访问
  3. 高效的内存操作能力

在 WebAssembly、WebGL、文件处理等场景中发挥着不可替代的作用。正确理解其工作原理并与普通数组合理选择使用,可以显著提升应用性能和处理复杂数据的能力。

到此这篇关于JavaScript ArrayBuffer 详解与使用完全指南的文章就介绍到这了,更多相关js arraybuffer使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS实现checkbox互斥(单选)功能示例

    JS实现checkbox互斥(单选)功能示例

    这篇文章主要介绍了JS实现checkbox互斥(单选)功能,涉及JavaScript针对页面元素属性的判断及动态操作相关实现技巧,需要的朋友可以参考下
    2019-05-05
  • 微信小程序(订阅消息)功能

    微信小程序(订阅消息)功能

    这篇文章主要介绍了微信小程序订阅消息功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • JavaScript 数组运用实现代码

    JavaScript 数组运用实现代码

    复习一下JS中数组的运用。学习js数组的朋友可以参考下。
    2010-04-04
  • JavaScript事件详细讲解

    JavaScript事件详细讲解

    本文给大家介绍js事件详解,涉及到事件流,事件处理,事件对象等方面的知识,非常不错,具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-06-06
  • js 去掉字符串前后空格实现代码集合

    js 去掉字符串前后空格实现代码集合

    这篇文章主要介绍了js 去掉字符串前后空格实现代码集合,需要的朋友可以参考下
    2017-03-03
  • JavaScript 微任务和宏任务讲解

    JavaScript 微任务和宏任务讲解

    这篇文章主要分享了JavaScript 微任务和宏任务讲解,在js中,我们一般将所有的任务都分成两类,一种是同步任务,另外一种是异步任务。而在异步任务中,又有着更加细致的分类,那就是微任务和宏任务,下面来一起学习js中的微任务和宏任务吧
    2021-12-12
  • js 对象外部访问或者调用问题

    js 对象外部访问或者调用问题

    造成楼主的模糊的其实是this指向的问题,你可以用alert出this看看,他们分别指向的是什么,相信您就会明白了! 在您写的那个c中的this其实指向的是c 而不是abc!
    2008-11-11
  • JS遍历数组和对象的区别及递归遍历对象、数组、属性的方法详解

    JS遍历数组和对象的区别及递归遍历对象、数组、属性的方法详解

    本文给大家js遍历数组和遍历对象的区别,一般来说for用来遍历数组对象而for-in用来遍历非数组对象。接下来小编给大家带来了js遍历数组和对象的区别及js递归遍历对象、数组、属性的方法详解,一起看下吧
    2016-06-06
  • JavaScript实现简单的弹窗效果

    JavaScript实现简单的弹窗效果

    这篇文章主要为大家详细介绍了JavaScript实现简单的弹窗效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】

    微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】

    这篇文章主要介绍了微信小程序实现发送模板消息功能,结合实例形式分析了微信小程序实现通过openid推送消息给用户相关操作技巧,需要的朋友可以参考下
    2019-05-05

最新评论