JavaScript DataView:初学者指南

你好,未来的JavaScript大师们!今天,我们将踏上一段激动人心的旅程,探索DataView对象的世界。如果你之前从未听说过它们,不用担心——在本教程结束时,你将能够像专业人士一样处理二进制数据!

JavaScript - DataView

DataView是什么?

在我们深入细节之前,让我们从基础开始。想象你是一名侦探,刚刚收到了一个装满二进制数据的神秘包裹。你会怎么理解它们?这就是DataView派上用场的时候!

DataView对象允许你在ArrayBuffer中读取和写入多种数字类型,不受计算机的字节序(endianness)影响(别担心,稍后会解释这个)的影响。它就像是一个二进制数据的通用翻译器!

语法

让我们来看看如何创建一个DataView对象:

new DataView(buffer [, byteOffset [, byteLength]])

别被这个吓到了!它比看起来要简单。让我们分解一下:

  • buffer:这是我们ArrayBuffer,即我们二进制数据的容器。
  • byteOffset(可选):我们在缓冲区中想要开始读取的位置。
  • byteLength(可选):我们想要在视图中包含的字节数。

示例:创建一个DataView对象

让我们卷起袖子,创建我们的第一个DataView对象:

// 首先,我们创建一个16字节的ArrayBuffer
const buffer = new ArrayBuffer(16);

// 现在,让我们创建一个覆盖整个缓冲区的DataView
const view1 = new DataView(buffer);

// 让我们创建另一个DataView,从第12个字节开始,长度为4字节
const view2 = new DataView(buffer, 12, 4);

console.log(view1.byteLength); // 输出:16
console.log(view2.byteLength); // 输出:4

在这个例子中,我们首先创建了一个16字节的ArrayBuffer。把它想象成一个16像素的空白画布。然后,我们创建了两个DataView对象:

  1. view1 覆盖整个缓冲区。
  2. view2 从第12个字节开始,覆盖最后4个字节。

这就好像我们有两副不同的放大镜来看我们的数据!

JavaScript DataView属性

DataView带有一些方便的属性。让我们看看:

属性 描述
buffer 返回DataView引用的ArrayBuffer
byteLength 返回DataView的长度(以字节为单位)
byteOffset 返回DataView从其ArrayBuffer开始的偏移量(以字节为单位)

下面是如何使用这些属性:

const buffer = new ArrayBuffer(16);
const view = new DataView(buffer, 2, 12);

console.log(view.buffer);       // ArrayBuffer(16)
console.log(view.byteLength);   // 12
console.log(view.byteOffset);   // 2

在这个例子中,我们创建了一个从我们缓冲区的第2个字节开始,长度为12个字节的DataView。属性帮助我们确认这些细节。

JavaScript DataView方法

现在,让我们进入激动人心的部分——方法!DataView提供了读取和写入不同类型数字的方法。以下是最常用的方法表格:

方法 描述
getInt8(byteOffset) 在指定的字节偏移处获取一个有符号的8位整数
getUint8(byteOffset) 在指定的字节偏移处获取一个无符号的8位整数
getInt16(byteOffset [, littleEndian]) 在指定的字节偏移处获取一个有符号的16位整数
getUint16(byteOffset [, littleEndian]) 在指定的字节偏移处获取一个无符号的16位整数
getInt32(byteOffset [, littleEndian]) 在指定的字节偏移处获取一个有符号的32位整数
getUint32(byteOffset [, littleEndian]) 在指定的字节偏移处获取一个无符号的32位整数
getFloat32(byteOffset [, littleEndian]) 在指定的字节偏移处获取一个32位浮点数
getFloat64(byteOffset [, littleEndian]) 在指定的字节偏移处获取一个64位浮点数

对于每个get方法,还有相应的set方法。

让我们看看其中一些方法的使用:

const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);

// 让我们写入一些数据
view.setInt16(0, 42);
view.setFloat32(2, 3.14);

// 现在,让我们读取这些数据
console.log(view.getInt16(0));   // 输出:42
console.log(view.getFloat32(2)); // 输出:3.140000104904175

在这个例子中,我们在字节偏移0处写入一个16位整数(42),在字节偏移2处写入一个32位浮点数(3.14)。然后,我们读取这些值。注意,浮点数的值不完全是3.14——这是由于浮点数在二进制中的存储方式。

字节序的奥秘

记得我之前提到过字节序吗?现在是揭开这个奥秘的时候了!字节序是指字节组成较大数值的顺序。有两种类型:

  1. 小端序:最低有效字节在前。
  2. 大端序:最高有效字节在前。

可以把它想象成写数字:123是大端序(最高有效位在前),而321则是小端序。

DataView的美妙之处在于,它允许你在读取或写入多字节值时指定字节序。让我们看一个例子:

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

view.setUint16(0, 0x1234, true);  // true表示小端序
view.setUint16(2, 0x5678, false); // false(或省略)表示大端序

console.log(view.getUint16(0, true));  // 0x1234
console.log(view.getUint16(0, false)); // 0x3412
console.log(view.getUint16(2, true));  // 0x7856
console.log(view.getUint16(2, false)); // 0x5678

在这个例子中,我们以不同的字节序写入相同的值,然后以两种字节序读取它们。这就好比可以左右开弓阅读一本书!

结论

恭喜你!你已经迈出了进入DataView世界的第一步。我们介绍了创建DataView对象、使用它们的属性以及用它们的方法操纵数据。我们还揭开了字节序的奥秘!

记住,处理二进制数据一开始可能会让人望而生畏,但有了DataView,你手中就有一个强大的工具。它就像是为二进制数据准备的瑞士军刀——多功能、精确、极其有用。

在你继续JavaScript之旅时,你会发现DataView在处理复杂的二进制数据结构时非常有用,比如在文件格式或网络协议中使用的那些。继续练习,很快你就能像真正的编码侦探一样操纵位和字节!

Credits: Image by storyset