Skip to content

JavaScript 中的二进制 ​

JavaScript 中的 TypedArray 与 Buffer ​

TypedArray ​

这是 ES2015(又称 ES6) 中新出的一个接口,不能直接被实例化。

因为这个接口就是一个抽象接口,就像 Java 中的抽象接口一样,是不能被实例化的,只能实例化实现该接口的子类。Uint8Array 就是实现 TypedArray 接口的一个子类。

就 Nodejs 而言, 可以使用 Buffer 操作二进制数据, 那对前端 JS 而言, 在 TypeArray 出现之前, 是没有可以直接操作二进制数据的类的。

所以 TypeArray 接口的作用是操作二进制数据。

ArrayBuffer ​

TypedArray 的作用是操作二进制数据, 其内部还有一个 buffer 属性, 这个 buffer 就是 ArrayBuffer 实例.。ArrayBuffer 就存储了要操作的二进制数据。

因此可以知道, TypedArray 是一个操作二进制数据的接口, 内部的 ArrayBuffer 存储了要操作的二进制数据。

Unit8Array ​

实现了 TypedArray 接口的子类有很多, Unit8Array 就是其中一个, 这个子类表示: 数组中的每一个元素都是 8 个二进制位(1 个字节)的无符号整数。

无符号的含义是, 该二进制的首位不表示符号位. 而对于有符号的二进制位, 首位 1 表示负数。

所以 Unit8Array 中每个元素的取值范围应该是 0 ~ 255。

NameValueValue
二进制表示1000111100001111
无符号14315
有符号-1515

Buffer ​

Buffer 在前端 JS 中并不存在, 是 Node 专门提供用来操作二进制数据的, 因为对于后端来说, 操作二进制数据是比较基础的操作。

而在 ES6 的 TypeArray 推出之后, 自 Node 3.0.0 版本开始, Buffer 继承自 Unit8Array, 相当于是对 ES6 中的 TypeArray 做兼容。

总结 ​

  • TypedArray: ES6 提供的用来操作二进制数据的接口, 具体由子类实现。
  • ArrayBuffer: 在 TypedArray 内部, 存储了要操作的二进制数据。
  • Unit8array: 实现 TypedArray, 每个元素都占据一个字节。
  • Buffer: Node 中才有, 继承自 Unit8array, 拥有更多强大的二进制数据操作。

附:JavaScript 进制转换 ​

js
parseInt(num).toString(2); // 十进制转二进制
parseInt(num).toString(8); // 十进制转八进制
parseInt(num).toString(16); // 十进制转十六进制
parseInt(num, 2); // 二进制转十进制
parseInt(num, 8); // 八进制转十进制
parseInt(num, 16); // 十六进制转十进制
parseInt(num, 2).toString(8); // 二进制转八进制
parseInt(num, 8).toString(2); // 八进制转二进制
parseInt(num, 2).toString(16); // 二进制转十六进制
parseInt(num, 16).toString(2); // 十六进制转二进制
parseInt(num, 8).toString(16); // 八进制转十六进制
parseInt(num, 16).toString(8); // 十六进制转八进制

附:NodeJS base64 转 buffer ​

js
// 将base64编码的二进制报文解析成buffer
const b = new Buffer.from("KA==", "base64");
// 将buffer解析成hex字符串
const s = b.toString("hex");
// 将hex字符串解析成10进制整数
console.log(parseInt(s, 16));

附:JavaScript 二进制数组的几种应用 ​

AJAX ​

XMLHttpRequest 第一版 responseType 属性默认为 text。

XMLHttpRequest 第二版 XHR2 允许服务器返回二进制数据,这时分成两种情况:

  • 已知二进制数据类型:responseType 设为 arraybuffer。
  • 未知二进制数据类型:responseType 设为 blob。
js
const xhr = new XMLHttpRequest();
xhr.open("GET", someUrl);
xhr.responseType = "arraybuffer";

xhr.onload = function () {
  let arrayBuffer = xhr.response;
  // ···
};

xhr.send();

Canvas ​

首先看下面的例子:

js
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const uint8ClampedArray = imageData.data; // Canvas 元素输出的二进制像素数据,也是 TypedArray 数组

需要注意的是:Uint8ClampedArray 这个类型是针对 Canvas 元素的专有类型,它是专门针对颜色,取值只能是 0~255。

WebSocket ​

WebSocket 可以通过 ArrayBuffer,发送或接收二进制数据。

js
const socket = new WebSocket("ws://127.0.0.1:8081");
socket.binaryType = "arraybuffer";

// 等待直到 socket 打开
socket.addEventListener("open", function (event) {
  // 发送二进制数据
  const typedArray = new Uint8Array(4);
  socket.send(typedArray.buffer);
});

// 接受二进制数据
socket.addEventListener("message", function (event) {
  const arrayBuffer = event.data;
  // ···
});

Fetch API ​

Fetch API 取回的数据,就是 ArrayBuffer 对象。

js
fetch(url)
  .then(function (request) {
    return request.arrayBuffer();
  })
  .then(function (arrayBuffer) {
    // ...
  });

File API ​

如果知道一个文件的二进制数据类型,也可以将这个文件读取为 ArrayBuffer 对象。

js
const fileInput = document.getElementById("fileInput");
const file = fileInput.files[0];
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function () {
  const arrayBuffer = reader.result;
  // ···
};

最后编辑时间:

Version 4.3