我正在学习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);
答案 0 :(得分:6)
我会将原始评论转换为更全面的答案。
.length
计算的数组索引来自0
及以上。负索引被视为对象的属性,而不是数组值。正如您在下面的ECMAScript规范中所看到的,在给定一些特殊处理的情况下,数组索引基本上只是某些类型的属性值。
来自ECMAScript spec的第15.4节:
15.4数组对象
Array对象对某类属性名称进行特殊处理。当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2 ^ 32时,属性名P(以String值的形式)是数组索引。属性名称为数组索引的属性也称为元素。每个Array对象都有一个length属性,其值始终是小于2 ^ 32的非负整数。 length属性的值在数值上大于名称为数组索引的每个属性的名称;无论何时创建或更改Array对象的属性,都会根据需要调整其他属性以保持此不变量。具体来说,每当添加名称为数组索引的属性时,如果需要,将更改length属性,使其大于该数组索引的数值;每当更改length属性时,将自动删除名称为数值索引且值不小于新长度的每个属性。此约束仅适用于Array对象的自身属性,并且不受可能从其原型继承的长度或数组索引属性的影响。
此外,你永远不应该"iterate" arrays with a for-in-loop:
for (var i in a1)
迭代a1
的所有可枚举属性,其中包括所有数组索引,但也可以包含其他属性。如果您只想使用for
循环迭代数组元素,则应使用另一种形式:
for (var i = 0, len = a1.length; i < len; i++)
打字稍微多一些,但更安全。
或者,在更现代的浏览器中,您可以使用.forEach()
method。
答案 1 :(得分:1)
这是因为Javascript中的数组是zero-based,即它们从零开始并上升到length - 1
。
你通常会编写你的for循环,以便被这样的小于运算符绑定:
for(i = 0; i < arr.length; i++) {
// do something with arr[i]
}
答案 2 :(得分:0)
数组长度定义为最后一个元素的索引加一。数组不需要是连续的,这可能会产生奇怪的结果:
var myArray = [];
myArray[-42] = 1
myArray[1000] = 2;
document.write(myArray.length); // 1001