4

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

我总是for (var i in object)在遍历对象属性时使用。

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

我问的问题是:我应该for (i=0; ... )完全转储并for (var in ...)用于数组和对象吗是否有性能影响?为什么我要使用其中一个?

4

5 回答 5

2

我应该转储吗for

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

摘自MDN

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

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

于 2013-06-19T02:07:58.853 回答
2

我为你做了一个jsperf:

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

基本上,它正在测试性能,使用for(var i in array).

话虽如此,您不会放弃forfor for in

于 2013-06-19T02:13:43.977 回答
1

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

您应该使用for已经说明的其他答案。

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

var keys = Object.keys(myObject);
for(var i = 0, key; key = keys[i]; i++) {
    //...
}
于 2013-06-19T02:20:26.413 回答
1

如果你想有一个快速响应的代码,那么:

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

在对象数组中,您只能使用 for in... 但如果您的代码很好,则不会经常发生循环遍历对象的情况。

最快的循环:

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];
}

while 是旧浏览器中最快的循环.. 在新浏览器中,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
}

大多数人做的另一个错误是他们在循环中使用推送......在循环中执行推送意味着你每次都执行一个新函数。因为我们已经有“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.:请随时纠正我糟糕的英语,但不要触摸代码!。

于 2013-06-19T02:26:26.527 回答
0

另请注意,不能保证枚举的顺序,因此数组上的 for..in 可能会返回乱序的值。它还将列出所有属性,包括非数字属性(即不会通过迭代索引返回)和对象链上的可枚举属性,因此如果您只想要自己的属性,则[[Prototype]]必须始终将其与hasOwnProperty测试一起使用(最常见的情况)。

如果您使用的是 ES5 主机,那么您可以使用Object.getOwnPropertyNamesObject.keys等方法来获取自己的属性。但同样,不能保证订单。

最后,对于 fordowhile循环进行了高度优化,性能差异很小,并且在一个浏览器中更快的内容在另一种浏览器中可能会很慢。仅在性能成为问题时才使用适合和优化的东西。

于 2013-06-19T03:04:11.313 回答