用 blob 构造函数需传数组形式的 parts 和可选 options,type 必须是规范 mime 类型;blob 与 arraybuffer 互转须异步或包装,blob.slice() 零拷贝分片更优;createObjecturl 后必须 revoke 防内存泄漏。

怎么用 Blob 构造函数创建二进制对象
直接 new Blob() 就行,但传参格式错一点就静默失败或类型不对。它只接受三个参数:parts(必须是数组)、options(可选)、不支持单个字符串或 ArrayBuffer 直接传入。
-
parts必须是数组,哪怕只有一个元素也要包成[data];传字符串、ArrayBuffer或Uint8Array单独进去会报错或生成空 Blob -
options里type是 MIME 类型字符串,不是文件扩展名,写成"image/jpg"(错)不如"image/jpeg"(对) - 浏览器对
type不校验,但后续用URL.createObjectURL()或发请求时,服务端可能拒收不规范的 type
示例:
const blob = new Blob(["hello"], { type: "text/plain" });
注意:字符串自动转 UTF-8,如果想控制字节,得先用 TextEncoder 或 Uint8Array 构造二进制数据再塞进去。
Blob 和 ArrayBuffer / TypedArray 怎么互转
它们不是同一层概念:Blob 是不可变的文件抽象,ArrayBuffer 是内存块。互转必须走异步读取或复制,没有零拷贝捷径。
- 从
Blob→ArrayBuffer:只能用blob.arrayBuffer()(现代浏览器),别用已废弃的FileReader.readAsArrayBuffer() - 从
ArrayBuffer→Blob:必须包装成数组,new Blob([buffer], { type: "..." }),不能直接new Blob(buffer) -
Uint8Array要转Blob,先用.buffer取底层ArrayBuffer,否则传进去的是对象引用,Blob 会序列化成"[object Uint8Array]"
常见错误现象:new Blob([new Uint8Array([1,2,3])]).size === 15(因为被当字符串序列化了),正确写法是 new Blob([new Uint8Array([1,2,3]).buffer])。
立即学习“前端免费学习笔记(深入)”;
上传前处理二进制数据时,Blob 比 ArrayBuffer 有什么实际区别
核心在内存占用和分片能力:Blob 支持 .slice() 零拷贝切片,ArrayBuffer 切片要 .slice() 或 subarray(),但都是新视图,不复制内存;而真正上传时,fetch() 和 XMLHttpRequest 都原生支持 Blob,不用转。
- 大文件分片上传优先用
Blob.slice(),它返回新Blob,不触发内存复制,比手动用ArrayBuffer拆再构造成Blob更轻量 -
fetch()接收Blob时,浏览器内部会流式读取,不会一次性把整个 Blob 加载进 js 内存;但如果你先调blob.arrayBuffer(),就全载入内存了 - 兼容性注意:IE 完全不支持
Blob.prototype.slice(),如需支持得降级用FileReader+slice模拟
为什么 URL.createObjectURL(blob) 之后必须调 URL.revokeObjectURL()
不撤销会导致内存泄漏——Blob 数据一直驻留在内存中,即使页面没再引用那个 URL 字符串,浏览器也不会自动回收。
- 典型场景:图片预览、音频播放、PDF 预览后关闭弹窗,必须立刻
revokeObjectURL(),否则反复操作几次就卡死 - 容易踩的坑:在
img.onload或audio.oncanplay里 revoke,但加载失败时(如 404、跨域)不会触发,得同时监听onerror - 现代替代方案:如只是临时读取内容,优先用
blob.text()、blob.json()或blob.arrayBuffer(),避免创建 object URL
撤销不是“可选优化”,是资源清理的硬性步骤。尤其在单页应用里,路由切换频繁,忘了 revoke 的 Blob 会越积越多,直到用户刷新页面才释放。