javascript中for循环和for-in循环之间的区别

时间:2014-12-29 04:07:38

标签: javascript arrays for-loop for-in-loop

我发现javascript中for循环和for-in循环之间存在差异。

当我定义一个新数组时:

var a=new Array();

然后我将一些值放入但不连续,例如:

a[0]=0;a[1]=1;a[4]=4; 

当我使用for(i=0;i<5;i++)获取值并使用警报来显示它时,它与使用for(i in a)不同。

前一个将显示索引2,3中显示“未定义”的元素,而for-in仅显示索引0,1和4.可以有人告诉我原因吗?

10 个答案:

答案 0 :(得分:2)

for循环迭代它们直到i达到5,所以i = 0,1,2,3,4,5并迭代所有。但是for for循环遍历它们的属性只有0到5而不是你定义的0,1,4。

来自MDN

  

注意: for..in不应该用于迭代索引顺序很重要的数组。

     

数组索引只是具有整数名称的可枚举属性,并且与一般对象属性相同。无法保证for ... in将以任何特定顺序返回索引,并且它将返回所有可枚举属性,包括具有非整数名称和继承的属性。

     

因为迭代的顺序是依赖于实现的,所以迭代数组可能不会以一致的顺序访问元素。因此,当迭代访问顺序很重要的数组时,最好使用带有数字索引(或Array.forEach或for ... of循环)的for循环。

答案 1 :(得分:2)

for (... in ...)通常用于遍历对象的属性(javaScript用于关联数组),而典型的for循环用于顺序数组。

在您的示例中,您实际上是使用键0,1和4创建关联数组。如果您想要一个真正的javaScript数组,那么您可以使用a.push(0)a.push(1), etc ...以便将值顺序添加到数组的末尾。

使用顺序数组,语法for (var i = 0; i < arr.length; i++)使i计数从数组的长度开始减少0到1。这将允许i一个接一个地等于数组中的每个索引,允许您访问该数组中的每个元素。

然而,对于关联数组,键是非顺序的,因此使变量计数从0到1小于数组的长度&#39;不会产生预期的结果。在您的示例中,它接近工作,因为您手动创建的密钥恰好是0,1和4,几乎是顺序的。

如果您想要一个包含非连续键的数组 - &#39;非连续的&#39;如在0,1,4等中.--你应该使用对象,而不是数组,例如

var obj = {};
obj[0] = 0;
obj[1] = 1;
obj[4] = 4;

然后使用for (... in ...)循环将是正确的语法。

答案 2 :(得分:0)

for-in循环枚举变量的可枚举属性。对于您的阵列,&#34; 0&#34;,&#34; 1&#34;和&#34; 4&#34;在数组上添加为可枚举属性。因此,for-in循环仅在&#34; i&#34;。

中获得0,1和4

for循环适用于i = 0到5.因此您尝试访问2和3处的值,这显然是未定义的。

答案 3 :(得分:0)

语法

for (var k in obj)

实际上是for-each循环。它遍历对象的属性。您应该熟悉JavaScript对象。对象是键到值的映射。

因此,for-each循环对于对象非常有用。但是,当循环遍历数组时,使用常规for循环会更好。

以下是对象属性上使用的for-each循环的示例: http://jsfiddle.net/nbtLpw0z/

答案 4 :(得分:0)

我正在使用for-in循环,因为它是一种较短的形式,但有时您可能希望控制迭代变量。例如,如果要迭代偶数索引,则需要使用法线for循环:

for (var i = 0; i < myarray.length; i+=1) {...}

同样适用,例如,如果您想要向后迭代:

for (var i = myarray.length-1; i >= 0; i--) {...}

当然,对于对象,for-in循环允许您在迭代变量中获取属性名称。例如

 var obj = {year: 2014, city: "Surat"}
 for (var propn in obj) alert(propn + " = " + obj[propn]);

在您的示例中,我使用for-in因为您正在进行简单的迭代。此外,我认为在非优化的Javascript编译器/解释器中,for-in循环会更快,因为变量增量是在内部完成的。

答案 5 :(得分:0)

对于初学者来说,没有必要在数组上使用for in循环,因为JavaScript中的数组只能有有序的数字索引。因此,您可以在0array.length - 1范围之间的任何索引处访问数组,如果您想使用for in循环迭代数组,那么您当然可以使用常规for循环更合适。

当您已订购数字索引时,会使用for in循环。 JavaScript对象实际上是一个有序的哈希表。您可以使用in运算符访问JavaScript对象的键,该运算符返回对象的键,通过访问该键的对象,您可以获得值。

例如:

var obj = {
   hello: "world",
   world: "hello"
};

常规for循环不起作用,因此您需要使用for in循环。

for(var i in obj) console.log(obj[i]);

对象也不会返回足够精确的长度属性来迭代整个对象,因此绝对需要for in循环。

另请注意,通过为数组指定值而不是按照下一个空闲元素存在的顺序,将自动将undefined放在您跳过的元素中。

在您的示例中,数组看起来像这样:

[0, 1, undefined × 2, 4]

答案 6 :(得分:0)

建议使用

for-each循环来遍历对象属性,而对于数组,建议使用for循环。在您的情况下,您可以使用push()来获得相同的结果。

var a = []; //recommended way of declaring arrays over `new Arrays()`
a.push(0);
a.push(1);
a.push(4);
//usual for-loop
for (var i = 0; a.length > i; i++) //recommended
  console.log('a[', i, ']=', a[i]);
console.log('---------------------');
// for-each loop
for (var k in a) //not recommended
  console.log('a[', k, ']=', a[k]);
console.log('---------------------');
Open console...

var person = {
  'name': 'Adam'
};

for (var k in person)
  console.log('person.' + k, '=', person[k]);
console.log('----------------------');

person.age = 26; //new property

for (var k in person)
  console.log('person.' + k, '=', person[k]);
console.log('----------------------');

person['gender'] = 'Male'; //again a new property

for (var k in person)
  console.log('person.' + k, '=', person[k]);
console.log('----------------------');

person.name = 'Will'; //updating property

for (var k in person)
  console.log('person.' + k, '=', person[k]);
console.log('----------------------');
Open console...

答案 7 :(得分:0)

在引擎盖下,for-in循环只不过是for循环。 因为(i in x)被分解为 -

for(i=0;i<x.length;i++) {
if(x[i] != undefined)
console.log(x[i]);
}

答案 8 :(得分:0)

我已经阅读并听到了正常的循环:for(var i = 0; i < arr.length; i++)更快。但我会说使用for of

var arr = [1,2,3], obj = {x: 1, y:2};
for(var value of arr) console.log(value) // 1, 2, 3
for(var key in obj) console.log(key) // x, y
for(var key of Object.keys(obj)) console.log(key) // x, y

您可以使用Object.keys(obj)将对象的键转换为数组,并在其上调用Array.prototype方法

答案 9 :(得分:0)

你的&#34; for&#34;循环查看0-4中数组索引的所有值,因为这正是您要求它做的。所以它看一个[0]并找到一个值,然后一个[1](相同的交易),然后它转到[2]并意识到你从未初始化一个[2]的值,因此它&# 39;未定义。同样适用于[3],最后a [4]有一个值,所以它找到它。

这种&#34; for&#34; loop将检查每个索引是否已定义。

A&#34; for ... in ...&#34;循环只会检查初始值。您的数组有3个已初始化的值,因此它会检查这些值。它会按照指数的顺序向您显示,但指数实际上并不会影响它所看到的内容。所以,如果你改变了你的&#34; a [1]&#34;到&#34; a [3]&#34;和&#34; a [4]&#34;对于&#34; a [10]&#34;,当您使用&#34; for ... in ...&#34;时,您仍会得到完全相同的答案。循环。

相关问题