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

为什么JavaScript中的数组显示错误的长度,javascript,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.wr

我正在学习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);
var a1=新数组();

对于(var i=-100;i数组长度定义为最后一个元素加上一个元素的索引。数组不需要是连续的,这可能会产生奇怪的结果:

var myArray = [];
myArray[-42] = 1
myArray[1000] = 2;
document.write(myArray.length); // 1001

这是因为Javascript中的数组是,也就是说,它们从零开始,直到
长度-1

通常将for循环编写为由小于运算符绑定,如下所示:

for(i = 0; i < arr.length; i++) {
    // do something with arr[i]
}
for(i=0;i
我将把我的原始评论转换成更全面的答案


.length
中计数的数组索引从
0
开始向上。负索引被视为对象的属性,而不是数组值。从下面的ECMAScript规范中可以看出,数组索引本质上只是经过特殊处理的某些类型的属性值

根据本手册第15.4节:

15.4数组对象

数组对象对某类属性名给予特殊处理。属性名p(以字符串值的形式)是数组索引,当且仅当ToString(ToUint32(p))等于p和ToUint32(p)不等于2^32。属性名称为数组索引的属性也称为元素。每个数组对象都有一个长度属性,其值始终为小于2^32的非负整数。长度属性的值在数字上大于名称为数组索引的每个属性的名称;每当创建或更改数组对象时,根据需要调整其他属性以保持此不变量。具体而言,每当添加名称为数组索引的属性时,如果需要,长度属性将更改为该数组索引数值的一个以上;每当更改长度属性时,每个属性都将hose name是一个数组索引,其值不小于自动删除的新长度。此约束仅适用于数组对象的自身属性,不受从其原型继承的长度或数组索引属性的影响


此外,您不应:

迭代
a1
的所有可枚举属性,该属性将包括所有数组索引,但也可能包括其他属性。如果要使用
for
循环仅迭代数组元素,则应使用其他形式:

for (var i = 0, len = a1.length; i < len; i++) 
for(变量i=0,len=a1.length;i
打字稍微多一些,但安全多了


或者,在更现代的浏览器中,您可以使用
.length
中计数的。

数组索引从0开始向上。负索引被认为是对象的属性,而不是数组值。这就澄清了这一点。感谢jfriend00。使用
for(a1中的变量i)
for迭代数组是非常不合适的。千万不要使用那种循环来迭代数组-始终使用
for(var i=0;i
并避免负索引之类的事情。根据定义,数组中的元素从
0
length-1
您不应该在数组中使用负索引。请查看其他策略
for (var i = 0, len = a1.length; i < len; i++)