JavaScript中各种二进制对象关系的深入讲解

目录
  • 前言
  • 各种对象的关系
    • ArrayBuffer
    • TypedArray
      • Uint8ClampedArray
      • 字符的相互转换
    • DataView
    • Blob
      • URL
      • 数据读取
    • File
    • FileList
    • FileReader
  • 相关资料
  • 总结

前言

现代 JavaScript 要面临更加复杂的场景,对于各种类型的数据传输也多了起来,其中涉及二进制传输,为了方便处理数据提高效率于是创造了ArrayBuffer对象。

但是使用中会发现不仅仅有ArrayBuffer,还有TypedArray、DataView、Blob、FileReader等一系列对象,让人迷惑它们之间关系是什么?为什么有这么多的对象?带着问题查询了资料,试着梳理其中的关系。

各种对象的关系

ArrayBuffer

ArrayBuffer是 JavaScript 最基本的处理二进制的对象,描述的是一段连续的内存空间,其单位是字节(byte)。

const buffer = new ArrayBuffer(32);

这样我们就创建了一块 32 字节的内存区域,可以使用buffer.byteLength来查看其长度。

ArrayBuffer对象能做的操作不多,并且是不可编辑的。如果需要编辑数据,要利用另外两个对象TypedArray与

DataView。

TypedArray

TypedArray类型化数组,TypedArray本身不存储任何数据,只是专门用来查看ArrayBuffer数据,所以称之为,TypedArray不是某一个构造函数名,而是一组构造函数的统称。

  • Int8Array:1 比特,8 位有符号整数
  • Uint8Array:1 比特,8 位无符号整数
  • Uint8ClampedArray:1 比特,8 位无符号整数
  • Int16Array:2 比特,16 位无符号整数
  • Uint16Array:2 比特,16 位无符号整数
  • Int32Array:4 比特,32 位无符号整数
  • Uint32Array:4 比特,32 位无符号整数
  • Float32Array:4 比特,32 位无 IEEE 浮点数
  • Float64Array:8 比特,64 位无 IEEE 浮点数
  • BigInt64Array:8 比特,64 为二进制有符号整数
  • BigUint64Array:8 比特,64 位无符号整数

创建的时候可以传入长度、typedArray、ArrayBuffer、数组。当然也可以什么都不传入。

const uint1 = new Uint8Array(8);
const uint2 = new Uint16Array(new Uint8Array(8));
const uint3 = new Uint8Array(new ArrayBuffer(8));
const uint4 = new Uint8Array([1, 2, 3]);
const uint5 = new Uint8Array();

以上typedArray中,除了创建时传入ArrayBuffer不会新创建ArrayBuffer,其他在new过程中底层都会创建新的ArrayBuffer。可以使用arr.buffer来访问其引用的ArrayBuffer。

操作上普通数组的操作都能在TypedArray 中使用。但因为ArrayBuffer描述的是连续的内存区间,所以我们无法删除某一个值,只能分配为0,也没办法使用concat方法。

Uint8ClampedArray

Uint8ClampedArray相对特殊一点,在正负溢出的情况下处理不同。

其他对于存入越界数据仅保留最右边(低位)部分,抛弃溢出数据,而Uint8ClampedArray对越界数据都保存为255,对于传入的负数保存为0。

字符的相互转换

TypedArray不支出直接传字符串,所以需要先转码一下。

String → Unit8Array

 const string = "Hello";
Uint8Array.from(string.split(""), (e) => e.charCodeAt(0));

Unit8Array → String

 // 使用TextDecoder对象
const u8 = Uint8Array.of(72, 101, 108, 108, 111);
new TextDecoder().decode(u8);
// 使用fromCharCode转换
const u8 = Uint8Array.of(72, 101, 108, 108, 111);
Array.from(u8, (e) => String.fromCharCode(e)).join("");

DataView

以上数据除了uint2变量,其他都是单一的数据类型,uint2对象这种一段内存中存放了两种类型数据,称之为复合视图。JavaScript 中数据类型往往不那么单一,仅用TypedArray操作会更加麻烦,所以又有了DataView对象。DataView相对于TypedArray有着更加多种的操作方法。

const buffer = new ArrayBuffer(8);
const dataView = new DataView(buffer);

提供了getInt8、getUint8、getInt16、getUint16、getInt32、getUint32、getFloat32、getFloat64方法。

参数有两个,第一位是节序位置,第二位是字节序,非必填。返回值是相应位置的字节数据。

const d1 = dataView.getUint8(1);
const d2 = dataView.getUint8(1, true);

字节位置好理解,字节序可以阅读《理解字节序》,总的说就是:

  • 大端字节序(big endian):高位字节在前,低位字节在后,这是人类读写数值的方法。
  • 小端字节序(little endian):低位字节在前,高位字节在后,即以 0x1122 形式储存。

默认情况下使用的是大端字节序,如果要使用小端字节序需要传入true。

这样我们就有了基础的二进制的读写方案。可实际的应用场景中往往有更加复杂的数据,所以又针对专门的场景又衍生出Blob、FileReader等对象。

Blob

Blob,是Binary Large Object(二进制大型对象)的缩写。

与ArrayBuffer差异是,ArrayBuffer是单纯的二进制数据,而Blob是带MIME类型的二进制数据。并且可以方便的从String、ArrayBuffer、TypedArray、DataView、Blob生成为Blob对象。

const blob1 = new Blob(["hello"], { type: "text/plain" });
const blob2 = new Blob([new Uint8Array([72, 101, 108, 108, 111]), " ", "world"], { type: "text/plain" });

属性:

  • size:读取对象的字节大小。
  • type:读取写入的MIME类型

方法:

  • slice:提取Blob片段。

URL

在开发中我们获取到图片二进制数据,我们可以转换成base64写入src中,但如果数据量很大,或者视频数据,就会超过其允许长度。我们可以使用URL.createObjectURL来方便的创建一个资源的 URL。

const url = URL.createObjectURL(blob1);

会生成类似blob:https://example.com/a6728d20-2e78-4497-9d6c-0ed61b93f11e的资源 URL,可以直接写入src中使用。

在不用时使用URL.revokeObjectURL(url)销毁其引用,释放其内存占用。

数据读取

如果我们要查看其中数据的话,有两种方式。

第一种,使用Response对象,可以直接读取字符串数据或是arrayBuffer数据。

const responseText = await new Response(blob2).text();
const responseBuf = await new Response(blob2).arrayBuffer();

第二种,使用FileReader对象。

const reader = new FileReader();
reader.onload = function (e) {
    console.log(reader.result);
};
reader.readAsText(blob2);

File

File继承自Blob,并增加了文件相关的属性信息。

  • name:文件名
  • lastModified:最后修改时间的时间戳
  • lastModifiedDate:最后修改时间的Date对象
  • webkitRelativePath:文件的路径。在 input 中选择目录时,会设置这个属性,非标准特性

FileList

FileList对象是File对象的集合。一般出现在:

  • <input type="file">控件,其中files属性是一个FileList
  • 拖拽事件中产生的DataTransfer对象,其中files属性会是一个FileList

属性:

  • length:可以获取当前FileList包含多少个File

方法:

  • item(index):可获取指定索引位置的File数据,一般情况下直接使用FileList[index]替代了。

FileReader

FileReader在谈Blob一节有提到过,实际上FileReader对象就是专门用来读取Blob对象的,当然也包括扩展的File对象。

属性:

  • result:文件的内容。
  • readyState:状态。0:未加载;1:正在加载;2:加载完成。
  • error:加载数据时的错误信息。

事件:

  • onload:加载成功后触发。
  • onerror:加载错误时触发。
  • onabort:加载中断时触发。
  • onloadend:加载结束后触发。
  • onloadstart:加载开始时触发。
  • onprogress:加载中触发。

方法:

  • readAsText(blob, "utf-8"):以文本形式返回数据,第二个参数可设置文本编码。
  • readAsDataURL(blob):以Data URL的形式返回数据。
  • readAsArrayBuffer(blob):以ArrayBuffer形式返回数据。
  • abort:中止操作。

如上面的示例,就是以文本形式返回数据:

const reader = new FileReader();
reader.onload = function (e) {
    console.log(reader.result);
};
reader.readAsText(blob2);

相关资料

总结

到此这篇关于JavaScript中各种二进制对象关系的文章就介绍到这了,更多相关JS二进制对象关系内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript中各种二进制对象关系的深入讲解

    目录 前言 各种对象的关系 ArrayBuffer TypedArray Uint8ClampedArray 字符的相互转换 DataView Blob URL 数据读取 File FileList FileReader 相关资料 总结 前言 现代 JavaScript 要面临更加复杂的场景,对于各种类型的数据传输也多了起来,其中涉及二进制传输,为了方便处理数据提高效率于是创造了ArrayBuffer对象. 但是使用中会发现不仅仅有ArrayBuffer,还有TypedArray.DataVie

  • 深入浅析JavaScript中的RegExp对象

    JS中的正则对象 概述 正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用作按照"给定模式"匹配文本的工具.比如,正则表达式给出一个 Email 地址的模式,然后用它来确定一个字符串是否为 Email 地址. JavaScript 的正则表达式体系是参照 Perl 5 建立的. 新建正则表达式有两种方法.一种是使用字面量,以斜杠表示开始和结束. var regex = /xyz/; 另一种是使用 RegExp 构造函数

  • 带你彻底理解JavaScript中的原型对象

    一.什么是原型 原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承. 1.1 函数的原型对象 ​ 在JavaScript中,我们创建一个函数A(就是声明一个函数), 那么浏览器就会在内存中创建一个对象B,而且每个函数都默认会有一个属性 prototype 指向了这个对象( 即:prototype的属性的值是这个对象 ).这个对象B就是函数A的原型对象,简称函数的原型.这个原型对象B 默认会有一个属性 constructor 指向了这个函数A ( 意思就是说:c

  • JavaScript 中有关数组对象的方法(详解)

    JS 处理数组多种方法 js 中的数据类型分为两大类:原始类型和对象类型. 原始类型包括:数值.字符串.布尔值.null.undefined 对象类型包括:对象即是属性的集合,当然这里又两个特殊的对象----函数(js中的一等对象).数组(键值的有序集合). 数组元素的添加 arrayObj.push([item1 [item2 [. . . [itemN ]]]]); 将一个或多个新元素添加到数组结尾,并返回数组新长度 arrayObj.unshift([item1 [item2 [. . .

  • 浅谈JavaScript中Date(日期对象),Math对象

    Date对象 1.什么是Date对象? 日期对象可以储存任意一个日期,并且可以精确到毫秒数(1/1000 秒). 语法:var Udate=new Date(); 注:初始值为当前时间(当前电脑系统时间). 2.Date对象常用方法: 3.Date方法实例 复制代码 代码如下: var newTime=new Date();//获取当前时间             var millSecond=Date.now();//当前日期转换成的毫秒数             var fullYear=n

  • 深入浅析JavaScript中的arguments对象(强力推荐)

    1.在JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性.arguments非常类似Array,但实际上又不是一个Array实例.可以通过如下代码得以证实(当然,实际上,在函数funcArg中,调用arguments是不必要写成funcArg.arguments,直接写arguments即可). Array.prototype.testArg = "test"; function funcArg() { alert(funcArg.arg

  • JavaScript中访问id对象 属性的方式访问属性(实例代码)

    实例如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Co

  • JavaScript中的Array 对象(数组对象)

     1.创建Array对象方法: --->var arr = [1,2,3];//简单的定义方法 此时可以知道 arr[0] == 1; arr[1] == 2; arr[2] == 3; --->new Array(); var arr = new Array();//定义一个没有任何内容的数组对象,然后以下面的方式为其赋值 arr[0] = "arr0"; arr[1] = "arr1"; arr[2] = "arr2"; ---&

  • Javascript中的arguments对象

    在js中一切都是对象,连函数也是对象,函数名其实是引用函数定义对象的变量. 1.什么是arguments? 这个函数体内的arguments非常特殊,实际上是所在函数的一个内置类数组对象,可以用数组的[i]和.length. 2.有什么作用? js语法不支持重载!但可用arguments对象模拟重载效果. arguments对象:函数对象内,自动创建的专门接收所有参数值得类数组对象. arguments[i]: 获得传入的下标为i的参数值 arguments.length: 获得传入的参数个数!

  • JavaScript中访问节点对象的方法有哪些如何使用

    JavaScript中访问节点对象的方法有哪些? 复制代码 代码如下: var obj = document.getElementById('fdafda'); var obj = document.f1; obj.method="post"; obj.action='Bb'; var obj = document.f1.userName; var obj = document.forms[0].userName; var obj = document.forms[0].element

随机推荐