很多前端童鞋对二进制有一种天生的恐惧,觉得遥不可及。本文将带你从基础到实践,全面掌握日常生活中可能会遇到的二元运算。文中穿插的一些知识点,大家可以多想想,相信会对你有所帮助~二进制数组是一种类似于数组的对象,它提供了一种访问原始二进制数据的机制。对于音频和视频编辑、访问WebSockets原始数据等,通过类型化数组操作二进制数据将非常有帮助。二进制数组由三种类型的对象组成:ArrayBuffer对象、TypedArray视图和DataView视图。下面只介绍前两者。ArrayBuffer对象表示一个通用的、固定长度的二进制数据缓冲区,它根本没有格式,也不提供访问其内容的机制。只能通过TypeArray视图进行读写。//参数为空位的字节长度constbuffer=newArrayBuffer(32);上面代码分配了一块连续的32字节内存空间,每个字节的值默认为0。支持的方法://缓冲区占用的字节长度buffer.byteLength//32//复制前两个字节并返回一个新的ArrayBuffer对象//先创建一个长度为16字节的内存,然后复制前两个字节过去复制的字节部分。buffer.slice(0,2)TypedArray视图该视图提供上下文,即数据类型、起始偏移量和元素数,将数据转换为实际的类型化数组,并以指定格式解释二进制数据。包含多种view类型,一般公式为Array:Int8Array,Unit8Array,Int16Array,Uint16Array...view之间的区别是一个view窗口占多少位,比如Int16Array,表示该窗口占用2个字节。如何创建视图模式1:TypedArray(buffer,byteOffset=0,length?)constbuffer=newArrayBuffer(12);//12bytesconstview16=newInt16Array(buffer,2,2)//每个窗口都是2个字节创建一个指向buffer的Int16视图,从字节2开始,长度为2。注意byteOffset必须是数字的整数倍窗口占用的字节数。比如上面的例子,只能是2或者4。方法二:TypedArray(length)constview16=newInt16Array(3);直接分配6字节(2*3)的内存空间。方法三:TypedArray(typedArray)constx=newInt8Array([1,1]);consty=newInt8Array(x);x[0]//1y[0]//1x[0]=2;y[0]//1y会先新建一块内存(2字节),然后将x的值复制到新的内存空间。方法四:TypedArray(arrayLikeObject)//可以接收一个数组作为参数constview16=newInt16Array([1,2,3]);同样的内存会被重新打开,参数数组对应的内存不会被共享。对于同一个buffer操作,共享内存TypedArray视图不存储数据,而是定义读写规则,修改底层ArrayBuffer,见示例://开辟一块内存空间buff=newArrayBuffer(32);//读取一次16位,即2个字节x16=newInt16Array(buff);x16[0]=1;//使用Int8Array作为窗口操作x8=newInt8Array(buff);x8[0]=2;x16[0]//2可以看到不同的视图对同一块内存进行操作,这就是内存共享。Symbol.iteratorconstview8=newInt8Array([1]);打印view8对象:view8的原型链:Int8Array->TypeArray->Object;可以看到length属性(注意length和byteLength的区别),Symbol.toStringTag,还有一个Symbol.iterator属性。这里我们介绍遍历器接口。我们知道一个对象是用Symbol.iterator部署的(不清楚的可以看ES6精读【焦点系列】(一)),也就是说可以遍历,所以可以用for...of://将类型数组转换为普通数组constnormalArray=[...typedArray];//orconstnormalArray=Array.from(typedArray);//orconstnormalArray=Array.prototype.slice.call(typedArray);supportedmethods普通数组的操作方法和属性,基本适用于TypedArray数组。1)从TypedArray中获取ArrayBufferconstarray=newInt16Array([1,2,3]);array.buffer//TypedArray->ArrayBuffer2)CopyTypeArray//将typedarray放在offset处typedarray.set(typedarray,offset);3)长度和字节长度consta=newInt16Array(8);a.length//8a.byteLength//16二进制读取顺序首先看下例中的v16[0]是什么?buffer=newArrayBuffer(2);v8=newInt8Array(buffer);v16=newInt16Array(buffer);v8[0]=1;v16[0]//??有的同学可能会想到://此时缓冲区中的值为:0000000100000000//V8窗口为1字节,则其值为:[00000001][00000000]=>[1,0]//因为V16有一个window2个字节,那么就很简单[0000000100000000]=>[256]其实就是你陷入了一个误区。机器和人是不同的。从左到右读取:地址空间中的高位字保存真实数据的高位,地址空间中的低位保存数据的低位,所以://buffer中的值在thistime:1000000000000000//V8的窗口是1个字节,那么它的值为:[10000000][00000000]=>[1,0]//由于V16的每个窗口是2个字节,所以很简单[1000000000000000]=>[1]应用1)XMLHttpRequest//AJAX默认返回文本数据,即responseType='text'xhr.responseType='arraybuffer'返回的response是ArrayBuffer类型。2)WebSockets可以直接发送或接收二进制数据。consttypedArray=newUint8Array(4);socket.send(typedArray.buffer);3)FetchAPI直接从response中读取arrayBuffer:response.arrayBuffer()Response的以下方法返回Promise对象:arrayBuffer()blob()json()text()formData()4)FileAPI需要使用FileReader:constfileInput=document.getElementById('fileInput');constfile=fileInput.files[0];constreader=newFileReader();reader.readAsArrayBuffer(file);reader.onload=function(){constarrayBuffer=reader.result;//···};mainmethod:readAsText()readAsDataURL()//dataUrlformreadAsArrayBuffer()abort()5)CanvasBlob表示一个不可变的、类似文件的原始数据对象。注意:File接口是基于Blob的,它继承了Blob的功能并对其进行了扩展以支持用户系统上的文件。语法varaBlob=newBlob(array,options);array:[ArrayBuffer|数组缓冲区视图|斑点|字符串]选项:{类型};type指定mineType,即mediaType示例://使用字符串创建blobvardebug={hello:"world"};varblob=newBlob([JSON.stringify(debug,null,2)],{类型:'应用程序/json'});除了原始字节之外,Blob和ArrayBuffer还提供我的类型作为元数据。//arrayBuffer到blobletv8=newInt8Array([1,2]);letblob=newBlob([v8]);//blob到arrayBufferblob.arrayBuffer().then(buffer=>console.log(buffer))//或newResponse(blob).arrayBuffer().then(buffer=>console.log(buffer))//或varreader=newFileReader();reader.addEventListener("loadend",function(){});reader.readAsArrayBuffer(blob);Blob方法和属性大小//数据包含类型的字节数//FilemediaType.slice([start[,end[,contentType]]])//返回一个新的Blob//返回一个Promise.stream()。text().arrayBuffer()createObjectURL//将生成一个URL字符串,如blob:d3958f5c-0777-0845-9dcf-2cb28783acafleturl=URL.createObjectURL(myBlob);//它可以用作使用img的普通url。源代码=网址;参数对象:File对象、Blob对象或mediaSource对象。实例一:上传一张本地图片并显示在网页上(预览)本地上传图片->input[type=file]获取File对象->FileReader1)->Blob->createObjectURL//ObjectUrL2)->readAsDataURL()//DataUrL示例2:如何拼接两个音频获取请求音频资源->ArrayBuffer->TypeArray->set方法拼接成ATypeArray->ArrayBuffer->Blob->ObjectURL示例3:将json数据转demo.json并下载文件1)Text->DataURL//设置mediaType为application/octet-stream2)Text->Blob->ObjectURL//使用a标签下载示例4:大文件分片上传//获取文件letblob=document.getElementById("file").files[0];获取文件的大小letfileSize=blob.size;//假设每片为2MletperSize=1024*1024*2;//获取片数totalPieces=Math.ceil(filesize/perSize);//拆分文件发送start=0;while(startfilesize){end=filesize};letchunk=blob.slice(start,end);开始=结束;formData.append(名称,块,blob.name);//Sendfilechunk...}例5:node层如何解析出文件node层如何从multipart/form-data获取关键点是使用开始分隔符:--boundary和结束分隔符:--boundary--划分内容,然后使用Content-Disposition来标识文件。如果对你有帮助,请点赞或观看,谢谢~更多技术干货,欢迎关注【扫码关注】~参考:https://developer.mozilla.org...https://developer.mozilla.org...https://developer.mozilla。组织...https://es6.ruanyifeng.com/#d...