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

2022-04-15 0 436
目录
  • 前言
  • 各种对象的关系
    • 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);
              

              相关资料

              • MDN 相关的关键字
              • 现代 JavaScript 教程 第三部分 二进制数据,文件
              • 阮一峰 JavaScript 教程 浏览器模型相关章节

              总结

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

              免责声明:
              1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

              2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
              如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
              如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

              NICE源码网 JavaScript JavaScript中各种二进制对象关系的深入讲解 https://www.niceym.com/23583.html