JavaScript DataView

原创
admin 4个月前 (08-19) 阅读数 19 #JavaScript

DataView

DataView视图是一个可以从二进制ArrayBuffer对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。

描述

DataView提供了一种灵活的方式来读写ArrayBuffer中的数据,它允许开发者以不同的数据类型和字节序访问二进制数据。

字节序

多字节的数字格式在内存中的表示方式因机器架构而异——相关的解释请参阅字节序。DataView访问器提供了对如何访问数据的明确控制,而不管执行代码的计算机的字节序如何。

const littleEndian = (() => {
  const buffer = new ArrayBuffer(2);
  new DataView(buffer).setInt16(0, 256, true /* 小端对齐 */);
  // Int16Array 使用平台的字节序。
  return new Int16Array(buffer)[0] === 256;
})();
console.log(littleEndian); // true 或 false

64位整数值

某些浏览器不支持DataView.prototype.setBigInt64()和DataView.prototype.setBigUint64()。因此,要在代码中启用跨浏览器的64位操作,你可以实现自己的getUint64()函数,以获得精度达到Number.MAX_SAFE_INTEGER的值——这对于某些情况足够使用。

function getUint64(dataview, byteOffset, littleEndian) {
  // 将 64 位的数字拆分位两个 32 位(4 字节)的部分
  const left = dataview.getUint32(byteOffset, littleEndian);
  const right = dataview.getUint32(byteOffset + 4, littleEndian);

  // 将两个 32 位的值组合在一起
  const combined = littleEndian
    ? left + 2 ** 32 * right
    : 2 ** 32 * left + right;

  if (!Number.isSafeInteger(combined))
    console.warn(combined, "超过 MAX_SAFE_INTEGER。可能存在精度丢失。");

  return combined;
}

或者,如果你需要完整的64位的范围,你可以创建BigInt。此外,尽管原生BigInt比等效的用户态的库快得多,但由于其大小可变的性质,BigInt始终比JavaScript中的32位整数要慢得多。

const BigInt = window.BigInt,
  bigThirtyTwo = BigInt(32),
  bigZero = BigInt(0);
function getUint64BigInt(dataview, byteOffset, littleEndian) {
  // 将 64 位的数字拆分位两个 32 位(4 字节)的部分
  const left = BigInt(dataview.getUint32(byteOffset | 0, !!littleEndian) >>> 0);
  const right = BigInt(
    dataview.getUint32(((byteOffset | 0) + 4) | 0, !!littleEndian) >>> 0,
  );

  // 将两个 32 位的值组合在一起并返回该值
  return littleEndian
    ? (right << bigThirtyTwo) | left
    : (left << bigThirtyTwo) | right;
}

构造函数

DataView()
创建一个新的DataView对象。

实例属性

DataView.prototype[Symbol.toStringTag]
[Symbol.toStringTag]属性的初始值为字符串"DataView"。该属性用于Object.prototype.toString()。
DataView.prototype.buffer
ArrayBuffer是引用该缓冲区的视图。在构造时会被固定,因此该属性只读
DataView.prototype.byteLength
视图的长度(以字节为单位)。在构造时会被固定,因此该属性只读
DataView.prototype.byteOffset
至ArrayBuffer的视图开始位置的字节偏移量。在构造时会被固定,因此该属性只读

实例方法

DataView.prototype.getBigInt64()
从当前DataView的指定字节偏移处读取8个字节,并将其解释为64位有符号整数。
DataView.prototype.getBigUint64()
从当前DataView的指定字节偏移处读取8个字节,并将其解释为64位无符号整数。
DataView.prototype.getFloat16()
从当前DataView的指定字节偏移处读取2个字节,并将其解释为16位浮点数。
DataView.prototype.getFloat32()
从当前DataView的指定字节偏移处读取4个字节,并将其解释为32位浮点数。
DataView.prototype.getFloat64()
从当前DataView的指定字节偏移处读取8个字节,并将其解释为64位浮点数。
DataView.prototype.getInt16()
从当前DataView的指定字节偏移处读取2个字节,并将其解释为16位有符号整数。
DataView.prototype.getInt32()
从当前DataView的指定字节偏移处读取4个字节,并将其解释为32位有符号整数。
DataView.prototype.getInt8()
从当前DataView的指定字节偏移处读取1个字节,并将其解释为8位有符号整数。
DataView.prototype.getUint16()
从当前DataView的指定字节偏移处读取2个字节,并将其解释为16位无符号整数。
DataView.prototype.getUint32()
从当前DataView的指定字节偏移处读取4个字节,并将其解释为32位无符号整数。
DataView.prototype.getUint8()
从当前DataView的指定字节偏移处读取1个字节,并将其解释为8位无符号整数。
DataView.prototype.setBigInt64()
指定一个数字,并将其作为64位有符号整数存储在当前DataView的指定字节偏移处的8个字节中。
DataView.prototype.setBigUint64()
指定一个数字,并将其作为64位无符号整数存储在当前DataView的指定字节偏移处的8个字节中。
DataView.prototype.setFloat16()
指定一个数字,并将其作为16位浮点数存储在当前DataView的指定字节偏移处的2个字节中。
DataView.prototype.setFloat32()
指定一个数字,并将其作为32位浮点数存储在当前DataView的指定字节偏移处的4个字节中。
DataView.prototype.setFloat64()
指定一个数字,并将其作为64位浮点数存储在当前DataView的指定字节偏移处的8个字节中。
DataView.prototype.setInt16()
指定一个数字,并将其作为16位有符号整数存储在当前DataView的指定字节偏移处的2个字节中。
DataView.prototype.setInt32()
指定一个数字,并将其作为32位有符号整数存储在当前DataView的指定字节偏移处的4个字节中。
DataView.prototype.setInt8()
指定一个数字,并将其作为8位有符号整数存储在当前DataView的指定字节偏移处的1个字节中。
DataView.prototype.setUint16()
指定一个数字,并将其作为16位无符号整数存储在当前DataView的指定字节偏移处的2个字节中。
DataView.prototype.setUint32()
指定一个数字,并将其作为32位无符号整数存储在当前DataView的指定字节偏移处的4个字节中。
DataView.prototype.setUint8()
指定一个数字,并将其作为8位无符号整数存储在当前DataView的指定字节偏移处的1个字节中。

示例

使用DataView

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

view.setInt16(1, 42);
view.getInt16(1); // 42

规范

Specification
ECMAScript® 2026 Language Specification
# sec-dataview-objects

浏览器兼容性

DataView在现代浏览器中得到广泛支持,包括Chrome、Firefox、Safari和Edge。自2015年7月以来,它已在所有主流浏览器中可用。

参见

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权本站发表,未经许可,不得转载。

上一篇:JavaScript布尔 下一篇:JavaScript日期
作者文章
热门
最新文章
标签列表