RangeError: invalid array length
当指定一个数组长度为负数、浮点数或超过平台支持的最大值时(即创建 Array 或 ArrayBuffer 时,或设置 length 属性时),会发生 JavaScript 异常“数组长度无效”。
允许的最大数组长度取决于平台、浏览器和浏览器版本。对于 Array,最大长度为 232-1。对于 ArrayBuffer,在 32 位系统上最大长度为 231-1 (2GiB-1)。从 Firefox 89 版本开始,在 64 位系统上 ArrayBuffer 的最大值为 233 (8GiB)。
注意: Array 和 ArrayBuffer 是独立的数据结构(一个的实现不会影响另一个)。
消息
RangeError: invalid array length (V8-based & Firefox) RangeError: Array size is not a small enough positive integer. (Safari) RangeError: Invalid array buffer length (V8-based) RangeError: length too large (Safari)
错误类型
RangeError
哪里出错了?
尝试创建长度无效的 Array 或 ArrayBuffer 时可能会出现此错误,包括:
- 通过构造函数或设置
length属性指定负长度。 - 通过构造函数或设置
length属性指定非整数长度。(ArrayBuffer构造函数会将长度强制转换为整数,但Array构造函数不会。) - 超过平台支持的最大长度。对于数组,最大长度为 232-1。对于
ArrayBuffer,在 32 位系统上最大长度为 231-1 (2GiB-1),或在 64 位系统上为 233 (8GiB)。这可能通过构造函数、设置length属性或隐式设置长度属性的数组方法(如push和concat)发生。
如果您使用构造函数创建 Array,您可能希望改用字面量表示法,因为第一个参数会被解释为 Array 的长度。否则,您可能希望在设置长度属性或将其用作构造函数的参数之前限制长度。
示例
无效案例
js
new Array(2 ** 40);
new Array(-1);
new ArrayBuffer(2 ** 32); // 32-bit system
new ArrayBuffer(-1);
const a = [];
a.length -= 1; // set the length property to -1
const b = new Array(2 ** 32 - 1);
b.length += 1; // set the length property to 2^32
b.length = 2.5; // set the length property to a floating-point number
const c = new Array(2.5); // pass a floating-point number
// Concurrent modification that accidentally grows the array infinitely
const arr = [1, 2, 3];
for (const e of arr) {
arr.push(e * 10);
}
有效情况
js
[2 ** 40]; // [ 1099511627776 ]
[-1]; // [ -1 ]
new ArrayBuffer(2 ** 31 - 1);
new ArrayBuffer(2 ** 33); // 64-bit systems after Firefox 89
new ArrayBuffer(0);
const a = [];
a.length = Math.max(0, a.length - 1);
const b = new Array(2 ** 32 - 1);
b.length = Math.min(0xffffffff, b.length + 1);
// 0xffffffff is the hexadecimal notation for 2^32 - 1
// which can also be written as (-1 >>> 0)
b.length = 3;
const c = new Array(3);
// Because array methods save the length before iterating, it is safe to grow
// the array during iteration
const arr = [1, 2, 3];
arr.forEach((e) => arr.push(e * 10));