提问人:Vishal 提问时间:8/19/2023 更新时间:8/19/2023 访问量:47
如何在 JavaScript 中为数组分配内存?
How is memory allocated for arrays in JavaScript?
问:
我希望下面的程序能够输出 40,000 字节(200 * 200 * 8 位数组或 1 个字节),但它在插入 .为什么?159800
200
当它在插入 () 时输出,在插入 () 时输出时,即使它始终是 8 位数组,它也会变得更加混乱。119800
10
subArray[j][0]=10
79800
1
subArray[j][0]=1
如果我更改为,对于相同的数字,输出的值完全相同。Uint8Array(1)
Uint16Array(1)
数组是如何工作的?
let x = 200
let y = 200
const changes =[]
for (let i=0;i<y;i++) {
const subArray = []
for (let j=0;j<x;j++) {
subArray[j] = new Uint8Array(1);
subArray[j][0]=200
}
changes[i]=subArray;
}
console.log(new Blob(changes).size);
答:
4赞
Pointy
8/19/2023
#1
U 是一个普通的数组,恰好填充了 Uint8Array 实例。如果您更改代码,使其改为 200 字节的类型化数组,您将得到预期的答案:subArray
let x = 200
let y = 200
const changes =[]
for (let i=0;i<y;i++) {
const subArray = new Uint8Array(200);
for (let j=0;j<x;j++) {
subArray[j] = 200;
}
changes[i]=subArray;
}
console.log(new Blob(changes).size); // 40000
该规范没有说明如果其中一个“blob 部分”是类型化数组的普通数组会发生什么。它可能正在将数组转换为字符串,但我不能说这在内部究竟是如何发生的。(e:实际上我可以,我想;见下文。
我要说的是规范,它说明了传递给 Blob 构造函数的“blob 部件”参数(在您的代码中)中的 3 种可能性会发生什么。每个部分可以是:changes
- 一个斑点;
- 缓冲区源(如类型化数组);
- 一个字符串。
所以没有提到“装满任何东西的普通阵列”。
编辑 — 如果你做一个小实验,很明显(嗯,很清楚)它正在将普通数组转换为字符串。这将需要将数组中的每个元素转换为字符串。使用值为 200 的单个字节转换 Uint8Array 时,将获得字符串“200”,即 3 个字符。当然,如果你用 10 进行初始化,你会得到“10”,而 1 会给你“1”。这(可能)解释了代码中的初始化值给出不同大小的答案这一事实:这是字符串值的大小差异,而不是字节。
let z = new Uint8Array([1, 2, 3]);
console.log(z[1]); // 2, as a number
let y = [z];
console.log(y.toString()); // '1,2,3' as a string
y = [z, z];
console.log(y.toString()); // '1,2,3,1,2,3'
评论
0赞
Vishal
8/19/2023
所以它在确定大小时很糟糕,因为它会转换为字符串?
0赞
Pointy
8/19/2023
@Vishal你的“子数组”是一个普通的 JavaScript 数组。它包含 Uint8Array 实例这一事实不会改变任何内容;Blob 构造过程会将其转换为字符串,因为这就是它所知道的与 Blob 或缓冲区源以外的任何内容有关的全部内容。
0赞
Pointy
8/19/2023
请注意,如果确实使用类型化数组为 Blob 构造函数创建一个数组,则它可以正常工作。
0赞
Vishal
8/19/2023
因此,使用 subArray 计算准确大小很糟糕。我明白了。这会是未来的改进吗?
0赞
Pointy
8/19/2023
@Vishal,它绝对不会试图这样做;它不会递归地下降到您传递它的数据结构中。
评论
Uint8Array
200 * 200 * 8 = 320000