javascript引擎对数组length赋值严格校验:先touint32转换,若结果≠原值或超出0~2³²−1范围即抛rangeerror;浮点数如3.5、1e21、nan及非纯数字字符串均非法,仅安全整数及可无损转为整数的字符串(如"5"、"")合法。

JavaScript 引擎对数组 length 属性的赋值有严格类型和范围校验,不是“先转成数字再用”,而是按明确规则判定是否合法。一旦不满足,立即抛出 RangeError: Invalid array length,且不会静默修正或四舍五入。
length 只接受安全的非负整数
引擎内部将 length 视为一个 32 位无符号整数(即 0 到 2³²−1 之间的整数),赋值时执行以下三步判断:
- 先调用
ToUint32抽象操作(不是Number()或parseInt) - 若结果不等于原始输入值(说明发生了截断或精度丢失),就视为非法
- 若结果超出 [0, 2³²−1] 范围,也视为非法
浮点数会被拒绝,哪怕看起来“很整”
例如 arr.length = 5.0 看似是整数,但 JS 引擎仍会拒绝——因为 ToUint32(5.0) === 5 成立,这其实不会报错;真正报错的是像 3.7、1e200 或 NaN 这类无法无损映射为 32 位整数的值。
常见误判示例:
-
arr.length = 3.0→ 合法(ToUint32(3.0) === 3,且 3 在范围内) -
arr.length = 3.5→ 报错(ToUint32(3.5) === 3,但 3 ≠ 3.5) -
arr.length = 1e21→ 报错(超出 2³²−1 ≈ 4.3e9) -
arr.length = -1→ 报错(ToUint32(-1) === 4294967295,但该值 ≠ −1)
字符串会尝试转换,但只接受纯数字形式
引擎会对字符串执行 ToNumber,再走上述整数校验流程:
-
arr.length = "5"→ 合法(转为数字 5,ToUint32(5) === 5) -
arr.length = "5.0"→ 合法(转为 5.0,再校验通过) -
arr.length = "5.5"→ 报错(转为 5.5,ToUint32(5.5) === 5 ≠ 5.5) -
arr.length = "abc"→ 报错(转为NaN,ToUint32(NaN) === 0,但 0 ≠ NaN) -
arr.length = ""→ 合法(转为 0,ToUint32(0) === 0)
为什么设计成这样?
这是为了保障数组底层内存模型的一致性。JS 数组在 V8 等引擎中实际以连续或半连续结构存储,length 直接控制索引边界与分配策略。允许浮点或模糊字符串赋值会导致:
- 索引计算歧义(如
arr[3.5]本就不合法) - 内存分配异常(如申请 1e100 个槽位)
- 与 TypedArray、WebAssembly 等底层机制不兼容










