我应该将哪个for循环用于JavaScript数组和对象?

时间:2013-06-19 02:06:09

标签: javascript arrays loops object for-loop

循环遍历数组时,我总是使用for (i=0; i<array.length; i++)

循环访问对象属性时,我总是使用for (var i in object)

我无法将for (i=0; ... )用于对象属性,但我可以对数组使用for (var in ...),因为数组也是对象。

我问的问题是:我应该完全转储for (i=0; ... )并将for (var in ...)用于两个数组和对象吗?是否有性能受损?为什么我会使用一个而不是另一个?

5 个答案:

答案 0 :(得分:2)

  

我应该转储for

你不应该。 for..in用于循环数组时不关心索引,它也会列出附加到对象的属性。坚持for表示数组,for..in表示对象。

摘自MDN

  

for..in不应该用于迭代索引顺序的数组   很重要......无法保证for..in将以任何特定顺序返回索引,并且它将返回所有可枚举属性...

至于性能,我不担心,因为显然不建议for..in循环索引数组。

答案 1 :(得分:2)

我为你做了一个jsperf:

http://jsperf.com/for-vs-for-in43

基本上,它正在测试性能,使用for(var i in array)时可以看到性能下降。

话虽如此,你不能放弃for for in

答案 2 :(得分:1)

  

不能用于(i = 0; ...)对象属性,但我可以使用   (var in ...)数组,因为数组也是对象。

您应该使用for,因为已经说明了其他答案。

但您可以使用Object.keys(yourObject)将对象的键列为数组,然后在该数组上使用for循环。

var keys = Object.keys(myObject);
for(var i = 0, key; key = keys[i]; i++) {
    //...
}

答案 3 :(得分:1)

如果您想拥有快速响应代码,那么:

对于数组,while( l--)for(i=0,..)循环是最快的...

在对象数组中,你只能用于...但如果你的代码很好,那么你经常不会经常在一个对象中循环。

最快的循环:

var myarray=[1,2,3,4,5,6],
length=myarray.length;//here i cache the length of the array.

缓存数组长度是保持代码快速的另一个重要因素。

while(length--){
//do somethingwith your array
 //myarray[length];
}

虽然是旧浏览器中最快的循环..在新浏览器中,看起来for循环更快一点。

for(var i=0;i<length;i++){
//do somethingwith your array
//myarray[i];
}

现在,如果您想定义变量,请在循环之前执行此操作。

还有一个很好的比较,即使有时候代码编写得不好也会向你展示性能。

http://jsperf.com/fors-vs-while/61

所以如果你计划循环一个数组,总是使用while--或for(var i = 0 ..)缓存长度。

另一个我非常喜欢的循环,如果你在像json这样的多维对象中有数组就是这个

for(var a=0,b;b=my.very.long.object[a];++a){
//do somethingwith your array 
//b
}

大多数人做的另一个错误是他们在循环中使用push ... 在循环中执行push意味着每次都执行一个新函数。 因为我们已经有了“i”这是一个索引我们可以设置它并使用它来直接存储数据而不执行新函数

所以

//wrong
for(var i=0,newArray=[];i<length;i++){
newArray.push(myarray[i]);//this is a waste of time and resources
}
//right
for(var i=0,newArray=[];i<length;i++){
newArray[i]=myarray[i];//we already have an index.
}

ps.:可以随意纠正我的坏英语,但不要触摸代码!。

答案 4 :(得分:0)

另请注意,枚举的顺序无法保证,因此对于数组而言,可能会不按顺序返回值。它还将列出所有属性,包括非数字的属性(即不会通过迭代索引返回)和对象的[[Prototype]]链上的可枚举属性,因此必须始终使用 hasOwnProperty 测试是否只需要自己的属性(最常见的情况)。

如果您使用的是ES5主机,则可以使用Object.getOwnPropertyNamesObject.keys之类的方法来获取自己的属性。但同样,订单无法保证。

最后, for ,而循环经过高度优化,性能差异很小,一个浏览器的速度更快另一个可能很慢。只有在性能问题时才使用适合和优化的东西。