为什么JavaScript中的数组显示错误的长度

101*_*01V 4 javascript

我正在学习Javascript.作为学习的一部分,我遇到了以下场景,我希望a1.length(代码的最后一行)显示201,但它显示101,任何想法?

var a1 = new Array();

for (var i = -100; i<=100; i++)
 a1[i]  = i;

for (var i in a1)
{
    document.write(i + "=" + a1[i])
    document.write("<br>");
}

document.write(a1.length);
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 6

我会将原来的评论转换为更彻底的答案.

.length0和向上计算的数组索引.负索引被视为对象的属性,而不是数组值.从下面的ECMAScript规范中可以看出,在给定一些特殊处理的情况下,数组索引基本上只是某些类型的属性值.

ECMAScript规范的第15.4节开始:

15.4数组对象

数组对象对特定类的属性名称进行特殊处理.当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2 ^ 32时,属性名P(以String值的形式)是数组索引.属性名称为数组索引的属性也称为元素.每个Array对象都有一个length属性,其值始终是小于2 ^ 32的非负整数.length属性的值在数值上大于名称为数组索引的每个属性的名称; 无论何时创建或更改Array对象的属性,都会根据需要调整其他属性以保持此不变量.具体来说,每当添加名称为数组索引的属性时,如果需要,将更改length属性,使其大于该数组索引的数值; 每当更改length属性时,将自动删除名称为数值索引且值不小于新长度的每个属性.此约束仅适用于Array对象的自身属性,并且不受可能从其原型继承的长度或数组索引属性的影响.


此外,您永远不应该使用for-in-loop"迭代"数组:

for (var i in a1)
Run Code Online (Sandbox Code Playgroud)

它迭代所有可枚举的属性,a1包括所有数组索引,但也可以包含其他属性.如果要仅使用for循环迭代数组元素,则应使用另一种形式:

for (var i = 0, len = a1.length; i < len; i++) 
Run Code Online (Sandbox Code Playgroud)

打字稍微多一点,但更安全.

或者,在更现代的浏览器中,您可以使用该.forEach()方法.