我被告知不要使用。。。在JavaScript中使用数组。为什么不呢?


当前回答

除了其他答案中给出的原因外,如果需要计算计数器变量,您可能不想使用“for…In”结构,因为循环会迭代对象财产的名称,因此该变量是一个字符串。

例如

for (var i=0; i<a.length; i++) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

将写入

0, number, 1
1, number, 2
...

鉴于

for (var ii in a) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

将写入

0, string, 01
1, string, 11
...

当然,这可以通过包括

ii = parseInt(ii);

但第一种结构更直接。

其他回答

孤立地说,在数组中使用for没有错。For-in迭代对象的属性名,在“现成”数组的情况下,财产对应于数组索引。(像length、toString等内置属性不包含在迭代中。)

然而,如果您的代码(或您正在使用的框架)将自定义财产添加到数组或数组原型中,那么这些财产将包含在迭代中,这可能不是您想要的。

一些JS框架,如Prototype修改了Array原型。像JQuery这样的其他框架则不然,因此使用JQuery,您可以在中安全地使用。

如果你有疑问,你可能不应该使用。

迭代数组的另一种方法是使用for循环:

for (var ix=0;ix<arr.length;ix++) alert(ix);

然而,这有一个不同的问题。问题是JavaScript数组可能有“洞”。如果您将arr定义为:

var arr = ["hello"];
arr[100] = "goodbye";

然后数组有两个项目,但长度为101。在中使用for将产生两个索引,而for循环将产生101个索引,其中99的值为undefined。

除了其他问题之外,“for…In”语法可能更慢,因为索引是字符串,而不是整数。

var a = ["a"]
for (var i in a)
    alert(typeof i)  // 'string'
for (var i = 0; i < a.length; i++)
    alert(typeof i)  // 'number'

for/in使用两种类型的变量:哈希表(关联数组)和数组(非关联)。

JavaScript将自动确定其通过项目的方式。因此,如果您知道数组确实是非关联的,可以使用(var i=0;i<=arrayLen;i++),并跳过自动检测迭代。

但在我看来,最好使用for/in,自动检测所需的过程非常小。

对此的真正答案将取决于浏览器解析器/解释JavaScript代码的方式。它可以在浏览器之间更改。

我想不出不使用for/in的其他目的;

//Non-associative
var arr = ['a', 'b', 'c'];
for (var i in arr)
   alert(arr[i]);

//Associative
var arr = {
   item1 : 'a',
   item2 : 'b',
   item3 : 'c'
};

for (var i in arr)
   alert(arr[i]);

因为它通过对象字段而不是索引枚举。你可以用索引“length”获得值,我怀疑你是否想要这个。

原因是一个构造:

变量a=[];//创建新的空数组。a[5]=5;//调整数组大小的完全合法的JavaScript。对于(var i=0;i<a.length;i++){//按照每个人的预期,在从0到5的数字索引上重复。控制台日志(a[i]);}/*将显示:未定义未定义未定义未定义未定义5.*/

有时可能完全不同:

变量a=[];a[5]=5;for(a中的var x){//仅显示显式设置的索引“5”,并忽略0-4console.log(x);}/*将显示:5.*/

还要考虑JavaScript库可能会这样做,这会影响您创建的任何数组:

//在JavaScript库的深处。。。Array.prototype.foo=1;//现在你不知道下面的代码会做什么。变量a=[1,2,3,4,5];for(a中的var x){//现在foo是每个数组的一部分//将在此处显示为“x”值。console.log(x);}/*将显示:01.2.3.4.食品*/