You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:05:59