为什么Javascript数组索引最多为4294967294而不是4294967295?

nop*_*ole 13 javascript

Javascript的索引是32位,所以似乎数组索引应该能够达到4294967295,共计4294967296个元素.但实际上最高的索引是4294967294.由于数组有一个length属性,我没有看到将null作为最后一个元素的原因.有没有理由最大指数是4294967294而不是4294967295?

Aad*_*hah 13

这是因为当您使用Array构造函数创建数组时,您可以为它提供一个可选项length,如下所示:

new Array(length);
Run Code Online (Sandbox Code Playgroud)

所述length阵列的是一个32位无符号整数.因此,阵列的长度可以是从哪个0Math.pow(2, 32) - 14294967295.

对于长度的数组n的索引范围从0n - 1.因此,JavaScript数组的最大索引是(Math.pow(2, 32) - 1) - 1Math.pow(2, 32) - 2,即4294967294.

因此,JavaScript数组可以包含最多4294967295元素而不是4294967296元素.

我知道.这是非常不合逻辑的,但是再一个元素不会产生很大的不同.

  • @NullUserException - JavaScript是一种解释型语言.因此,数据的内部表示在解释器的控制之下.规范只定义了一种数字数据类型 - "Number",即IEEE 754 double.因此它们在内部表示如此.但是,规范将数组的"length"范围定义为32位无符号整数.因此,解释器可以进行优化并在内部存储它.访问时,整数被强制为"Number".这取决于语言的实现,可能会有所不同. (3认同)
  • 我不确定这在技术上是否正确.虽然长度限制为4294967295(否则会引发RangeError),但我认为`.length`本身不是32位UInt.事实上,Chrome告诉我数组对象的`.length`类型是数字,当然其MAX_VALUE远大于4294967295. (2认同)
  • @NullUserException不要将构造函数参数与属性getter混淆.另外,仅仅因为`length`属性的类型是`number`并不意味着它可以采取所有可能的值.例如,`typeof Math.sin(x)`也是`number` ... (2认同)

Ted*_*opp 5

ECMA-262规范(部分15.4)表示:

属性名称P(以字符串值的形式)是数组索引,当且仅当 ToString(ToUint32( P )) 等于P且 ToUint32( P ) 不等于 2 32 -1。

规范还说length数组的属性总是小于2 32。这似乎将 4294967295 作为数组索引排除在外。