difference between for loop and for-in loop in javascript
我发现在javascript中for循环和for in循环之间存在差异。
定义新数组时:
1 | var a=new Array(); |
然后我将一些值放入,但不连续,例如:
1 | a[0]=0;a[1]=1;a[4]=4; |
当我使用
前一个将显示索引2、3中显示"未定义"的元素,而for-in将只显示索引0、1和4。有人能告诉我为什么吗?
在您的示例中,您实际上是使用键0、1和4创建关联数组。如果你想要一个真正的javascript数组,你可以使用
对于顺序数组,语法
但是,对于关联数组,键是非顺序的,因此使变量计数"从0到1小于数组长度"不会产生所需的结果。在您的示例中,它接近工作状态,因为您手工创建的键恰好是0、1和4,这几乎是连续的。
如果您想要一个具有非顺序键的数组--"非连续"如0、1、4等---
1 2 3 4 | var obj = {}; obj[0] = 0; obj[1] = 1; obj[4] = 4; |
然后使用
for循环对它们进行迭代,直到i达到5,所以i=0,1,2,3,4,5,并对所有元素进行迭代。但是对于for…in循环,只迭代您定义的属性0到5,而不是0,1,4。
来自MDN:
Note: for..in should not be used to iterate over an Array where index order is important.
Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.
Because the order of iteration is implementation dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index (or Array.forEach or the for...of loop) when iterating over arrays where the order of access is important.
您的"for"循环查看数组索引的所有值(从0到4),这正是您要求它做的。因此,它查看一个[0]并找到一个值,然后找到一个[1](相同的交易),然后转到一个[2]并意识到您从未初始化一个[2]的值,因此它是未定义的。同样的情况也适用于[3],最后一个[4]有一个值,所以它会找到它。
这种类型的"for"循环将检查每个索引,无论是否定义。
A…for…在…"循环将只检查初始化的值。您的数组有3个已初始化的值,因此它会检查这些值。它将按照索引的顺序向您显示它们,但这些索引实际上并不影响它所看到的内容。所以如果你把你的"A[1]改为"A[3]",把"A[4]改为"A[10]",当你用"for…在……"循环"中。
我读过,也听说过,循环正常:
1 2 3 4 | 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 |
可以使用
在引擎盖下,for-in循环只是for循环。因为(i in x)被分解为-
1 2 3 4 | for(i=0;i<x.length;i++) { if(x[i] != undefined) console.log(x[i]); } |
对于遍历对象属性,建议使用
1 2 3 4 5 6 7 8 9 10 11 12 | 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('---------------------'); |
1 | Open console... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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('----------------------'); |
1 | Open console... |
对于初学者来说,没有必要在数组上使用
如果没有顺序数字索引,则使用
例如:
1 2 3 4 | var obj = { hello:"world", world:"hello" }; |
常规for循环不起作用,因此不需要使用
对象也不会返回足够精确的长度属性来遍历整个对象,因此绝对需要一个
还要注意,如果不按下一个自由元素的存在顺序给数组赋值,则会自动将
在您的示例中,数组如下所示:
1 | [0, 1, undefined × 2, 4] |
我之所以使用in循环,是因为它的形式较短,但有时您可能希望控制迭代变量。例如,如果要在偶数索引上迭代,则需要使用normal for循环:
1 | for (var i = 0; i < myarray.length; i+=1) {...} |
例如,如果要向后迭代,则同样适用:
1 | for (var i = myarray.length-1; i >= 0; i--) {...} |
当然,对于对象,for-in循环允许您在迭代变量中获取属性名。
1 2 | var obj = {year: 2014, city:"Surat"} for (var propn in obj) alert(propn +" =" + obj[propn]); |
在您的示例中,我将在中使用,因为您正在执行一个简单的迭代。此外,我认为在非优化的JavaScript编译器/解释器中,for-in循环会更快,因为变量增量是在内部完成的。
句法
实际上是一个for each循环。它遍历对象的属性。您应该熟悉JavaScript对象。对象是键到值的映射。
因此,for each循环对于对象非常有用。但是,在数组中循环时,最好使用正则for循环。
下面是一个用于对象属性的for each循环的示例:http://jsfiddle.net/nbtlpw0z/。
for in循环枚举变量的可枚举属性。对于数组,"0"、"1"和"4"将作为可枚举属性添加到数组中。因此,对于in循环,在"i"中只得到0、1和4。
for循环在i=0到5之间工作。所以你试图访问2和3的值,这显然是未定义的。