JavaScript数组内存分配及Blob大小异常原因咨询
问题解析:Blob尺寸异常的原因及数组工作机制
核心原因
你看到的尺寸异常,本质是Blob构造函数对传入参数的类型处理逻辑导致的:
- 你创建的
changes是二维普通数组,每个子数组subArray也是普通数组,内部包含独立的Uint8Array/Uint16Array实例。 - Blob仅接受特定类型作为有效内容(ArrayBuffer、TypedArray、Blob、字符串等),普通数组不属于合法类型,因此浏览器会自动调用普通数组的
toString()方法,将其转换为字符串后再作为Blob内容。
具体尺寸计算逻辑
TypedArray的toString()方法会将自身元素转换为逗号分隔的字符串:
- 当
subArray[j][0] = 200时,每个Uint8Array(1)的toString()结果是"200",每个subArray(200个该实例)转换后的字符串是"200,200,...,200",总长度为3*200 + 199 = 799(3是"200"的字符数,199是逗号数量)。200个这样的子数组总字节数就是200*799 = 159800,和你看到的结果完全匹配。 - 当值为10时,每个实例的
toString()是"10",子数组转换后长度为2*200 +199=599,总尺寸200*599=119800。 - 当值为1时,每个实例的
toString()是"1",子数组转换后长度为1*200 +199=399,总尺寸200*399=79800。
为什么换Uint16Array结果不变?
不管是Uint8Array还是Uint16Array,只要内部存储的数值相同,toString()方法返回的字符串就完全一致(比如值为200时,两者的toString()都是"200"),因此转换后的字符串字节数不变,Blob尺寸自然相同。
如何得到预期的40000字节?
要让Blob直接使用TypedArray的二进制内容,需要将所有TypedArray放在一维数组中(而非嵌套普通数组)传给Blob,或者直接创建一个大的TypedArray:
方法1:使用一维数组存储TypedArray实例
let x = 200 let y = 200 const changes = [] for (let i=0;i<y;i++) { for (let j=0;j<x;j++) { const arr = new Uint8Array(1); arr[0] = 200; changes.push(arr); } } console.log(new Blob(changes).size); // 输出40000
方法2:创建单个大TypedArray(更高效)
let x = 200 let y = 200 const totalSize = x * y; const changes = new Uint8Array(totalSize); changes.fill(200); console.log(new Blob([changes]).size); // 输出40000
内容的提问来源于stack exchange,提问作者Vishal
相关产品推荐
相关产品推荐

