【发布时间】:2021-12-02 11:55:47
【问题描述】:
我有一个小的代码循环抛出 Uncaught RangeError: Invalid Array Length
我能够在 Google Chrome 控制台中使用它来重现它
const COUNT = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
for (let i = 0; i < COUNT; i++) {
xValues[i] = i;
yValues[i] = Math.sin(i * 0.000001);
}
console.log(`count: ${yValues.length}`);
这是开发者控制台中的输出
据我所知,Javascript 中的最大数组大小是 2^32-1?这里应该有足够的内存来分配,并且索引 i 永远不会是负数,也不会超出数组的边界。
奇怪的是,如果我使用这段代码,没有崩溃
const COUNT = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
for (let i = 0; i < COUNT; i++) {
xValues[i] = i;
yValues[i] = i;
}
console.log(`count: ${yValues.length}`);
分配给 yValues[i] 的值永远不会超出范围 -1、+1,因此我也不能将此视为数字超出范围的问题。
有人对此有所了解吗?
编辑:更新
另一个不起作用的场景。计算随机游走。
const count = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
let prevYValue = 0;
for (let i = 0; i < COUNT; i++) {
const curYValue = Math.random() - .5;
xValues[i] = i;
yValues[i] = prevYValue + curYValue;
prevYValue += curYValue;
}
这个也扔!但是
yValues[i] = i
很好¯\_(ツ)_/¯
编辑:更新 2
现在可以确认这是特定于浏览器的,如果您在 Firefox 中运行相同的测试,它可以工作,但浏览器要求您等待。
怀疑异常Uncaught RangeError 是错误报告的超时?
【问题讨论】:
-
有趣!当
i达到 5,592,406 FYI(至少在我的机器上)时,它会失败。 -
当
i === 5592406时,Math.sin()行上的 Chrome 和 Edge 都会中断。如果你从5592406开始,它会在11184812或(5592406 * 2)上中断,(5592406 * 3)也是如此...... -
yValues[5592406] = Math.sin(5592406 * 0.000001)单独通过,所以 RangeError not 似乎 only 与索引数量相关,但也以某种方式与内容相关存储在数组中? MDN 没有明确表示这种行为恕我直言。 -
与计算无关。你只需要一个数组就可以得到相同的结果,并为其分配一个浮点数,例如
0.5。行为上的差异显然与用于数组元素的内部数据类型有关:32 位整数或浮点数。请参阅分配1e9(是 32 位整数)或1e10(不是 32 位整数)的区别。与调用Math.random或Math.sin无关。 -
完成,报告为可能的 Chromium 错误 bugs.chromium.org/p/chromium/issues/detail?id=1275993
标签: javascript arrays