我发现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.可以有人告诉我原因吗?
答案 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和4for循环适用于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中的数组只能有有序的数字索引。因此,您可以在0
和array.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;时,您仍会得到完全相同的答案。循环。