当前位置: 首页 > Web前端 > JavaScript

理解JavaScript中各种二进制对象之间的关系

时间:2023-03-26 20:50:59 JavaScript

现代JavaScript要面对的场景越来越复杂,数据传输的种类越来越多,其中就涉及到二进制传输。为了方便数据处理,提高效率,创建了ArrayBuffer对象。但是在使用中,你会发现不仅仅是ArrayBuffer,还有TypedArray、DataView、Blob、FileReader等一系列对象,让人一头雾水。他们之间是什么关系?为什么会有这么多对象?我带着疑问查询资料,试图理清其中的关系。各种对象之间的关系ArrayBufferArrayBuffer是JavaScript中最基本的二进制处理对象,它描述了一个连续的内存空间,它的单位是字节(byte)。constbuffer=newArrayBuffer(32);这样,我们就创建了一个32字节的内存区域,我们可以使用buffer.byteLength来检查它的长度。ArrayBuffer对象能做的操作不多,而且是不可编辑的。如果您需要编辑数据,请使用另外两个对象TypedArray和DataView。TypedArrayTypedArray是类型化数组。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-bit非IEEE浮点数BigInt64Array:8位、64位二进制有符号整数BigUint64Array:8位、64位无符号整数。Length、typedArray、ArrayBuffer、array可以在创建时传入。当然,什么也不能传进去。constuint1=newUint8Array(8);constuint2=newUint16Array(newUint8Array(8));constuint3=newUint8Array(newArrayBuffer(8));constuint4=newUint8Array([1,2,3]);constuint5=newUint8Array();在上面的typedArray中,除了创建时传入的ArrayBuffer不会创建新的ArrayBuffer外,其他底层都会在new过程中创建新的ArrayBuffer。您可以使用arr.buffer访问它引用的ArrayBuffer。对普通数组进行操作的操作可以在TypedArray中使用。但是因为ArrayBuffer描述的是一个连续的内存范围,所以我们不能删除某个值,只能赋为0,没办法使用concat方法。Uint8ClampedArrayUint8ClampedArray比较特殊,在正溢出和负溢出的情况下处理不同。其他的只保留最右(下)部分的越界数据,将溢出的数据丢弃,而Uint8ClampedArray将越界数据保存为255,将传入的负数保存为0。字符的相互转换TypedArray不需要直接传字符串,所以需要先转码。String→Unit8Arrayconststring="Hello";Uint8Array.from(string.split(""),(e)=>e.charCodeAt(0));Unit8Array→String//使用TextDecoder对象constu8=Uint8Array.of(72,101,108,108,111);newTextDecoder().decode(u8);//使用fromCharCode转换constu8=Uint8Array.of(72,101,108,108,111);Array.from(u8,(e)=>String.fromCharCode(e)).join("");DataView中的上述数据除了uint2变量外,都是单一数据类型。uint2对象在一段内存中存储了两种类型的数据,这称为Compositeview。JavaScript中的数据类型往往不是那么单一,只用TypedArray来操作会比较麻烦,所以就有了DataView对象。与TypedArray相比,DataView的操作方法更多。constbuffer=newArrayBuffer(8);constdataView=newDataView(缓冲区);提供getInt8、getUint8、getInt16、getUint16、getInt32、getUint32、getFloat32、getFloat64方法。有两个参数,第一个是序列位置,第二个是字节序,可选。返回值为对应位置的字节数据。constd1=dataView.getUint8(1);constd2=dataView.getUint8(1,true);字节位置好理解,读字节序就可以《理解字节序》,一般来说:大端字节序(bigendian):高位字节在前,低位字节在后。这就是人类读取和写入值的方式。Littleendian:低位字节在前,高位字节在后,即以0x1122的形式存储。默认情况下,使用big-endian字节顺序。如果要使用little-endian字节序,需要传入true。这样我们就有了一个基本的二进制读写方案。但在实际应用场景中往往会有更复杂的数据,因此针对特定场景派生出Blob、FileReader等对象。BlobBlob是BinaryLargeObject(二进制大对象)的缩写。与ArrayBuffer的区别在于ArrayBuffer是纯二进制数据,而Blob是MIME类型的二进制数据。并且它可以轻松地从String、ArrayBuffer、TypedArray、DataView和Blob生成Blob对象。constblob1=newBlob(["hello"],{type:"text/plain"});constblob2=newBlob([newUint8Array([72,101,108,108,111]),"","world"],{type:"text/plain"});属性:size:读取对象的字节大小。类型:读写MIME类型方法:slice:提取Blob片段。在开发url的过程中,我们拿到了图片二进制数据,我们可以转成base64写入src,但是如果数据量很大,或者是视频数据,就会超过它允许的长度。我们可以使用URL.createObjectURL来方便地创建资源URL。consturl=URL.createObjectURL(blob1);会生成类似blob的资源URL:https://example.com/a6728d20-2e78-4497-9d6c-0ed61b93f11e,可以直接写入src中使用。在不使用时,使用URL.revokeObjectURL(url)销毁它的引用并释放它的内存使用。数据读取如果我们要查看数据,有两种方式。第一种,使用Response对象,可以直接读取string数据或者arrayBuffer数据。constresponseText=awaitnewResponse(blob2).text();constresponseBuf=awaitnewResponse(blob2).arrayBuffer();其次,使用FileReader对象。constreader=newFileReader();reader.onload=function(e){console.log(reader.result);};reader.readAsText(blob2);FileFile继承自Blob,增加了文件相关的属性信息。name:文件名lastModified:最后修改时间的时间戳lastModifiedDate:最后修改时间的Date对象webkitRelativePath:文件的路径。在输入的非标准功能中选择目录时设置此属性。FileListFileList对象是File对象的集合。一般出现在:控件,其中files属性是一个FileList拖拽事件中产生的DataTransfer对象,这里files属性会是一个FileList属性:length:当前FileList包含多少个Files获取方法:item(index):可以获取指定索引位置的File数据,一般直接使用FileList[index]代替。FileReaderFileReader在Blob部分提到。其实FileReader对象就是专门用来读取Blob对象的,当然也包括扩展的File对象。属性:result:文件内容。readyState:状态。0:不加载;1:加载;2:加载完成。错误:加载数据时的错误信息。事件:onload:加载成功后触发。onerror:加载错误时触发。onabort:加载中断时触发。onloadend:加载结束后触发。onloadstart:加载开始时触发。onprogress:加载过程中触发。方法:readAsText(blob,"utf-8"):返回文本形式的数据,第二个参数可以设置文本编码。readAsDataURL(blob):以DataURL的形式返回数据。readAsArrayBuffer(blob):以ArrayBuffer的形式返回数据。中止:中止操作。如上例,数据以文本形式返回:constreader=newFileReader();reader.onload=function(e){console.log(reader.result);};reader.readAsText(blob2);相关资料MDN相关关键词现代JavaScript教程第三部分二进制数据、文档阮一峰JavaScript教程浏览器模型相关章节