我应该为 JavaScript 数组和对象使用哪个 for 循环? [复制]
Posted
技术标签:
【中文标题】我应该为 JavaScript 数组和对象使用哪个 for 循环? [复制]【英文标题】:Which for loop should I use for JavaScript arrays and objects? [duplicate] 【发布时间】:2013-06-15 10:21:45 【问题描述】:我在遍历数组时总是使用for (i=0; i<array.length; i++)
。
循环对象属性时,我总是使用for (var i in object)
。
我不能将for (i=0; ... )
用于对象属性,但我可以将for (var in ...)
用于数组,因为数组也是对象。
我要问的问题是:我应该完全转储for (i=0; ... )
并将for (var in ...)
用于 数组和对象吗?有性能冲击吗?为什么我要使用一个而不是另一个?
【问题讨论】:
这几乎是一个重复,或者至少与an S.O. question viewed over 160K times密切相关。 @RayToal 我同意。这里的“相关问题”系统很好,但似乎还不够好。 :) 但是我担心另一个问题没有提出的一件事:性能。 同意。很难知道问题何时几乎相同。但是,我链接到的那个应该有一些很好的理由来避免数组的 for-in,因此应该对您有所帮助。很好的一点是性能方面没有被涵盖! 实际上性能是在链接到 this article 的 cmets 之一中解决的 :) 【参考方案1】:我应该转储
for
你不应该。 for..in
用于循环数组时不关心索引,它也会列出附加到对象的属性。对数组使用for
,对对象使用for..in
。
摘自MDN:
for..in
不应用于迭代索引顺序的数组 很重要...不能保证for..in
会以任何特定顺序返回索引,并且会返回所有可枚举的属性...
至于性能,我不担心,因为for..in
循环索引数组显然不推荐。
【讨论】:
【参考方案2】:我为你做了一个jsperf:
http://jsperf.com/for-vs-for-in43
基本上,它是在测试性能,使用for(var i in array)
时您会看到性能大幅下降。
话虽如此,你不应该放弃for
for for in
。
【讨论】:
+1 用于解决 OP 问题的性能。【参考方案3】:不能将 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++)
//...
【讨论】:
虽然由于浏览器支持我犹豫要不要使用它,但这听起来是个不错的方法。 +1 @Jared true,虽然支持非常好,但不包括旧版 IE 和 Opera:kangax.github.io/es5-compat-table 我正在倒计时,直到我可以停止支持 IE8。【参考方案4】:如果您想要快速响应的代码,那么:
对于数组,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
大多数人犯的另一个错误是他们在循环中使用 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.:请随时纠正我糟糕的英语,但不要碰代码!.
【讨论】:
【参考方案5】:还要注意,枚举的顺序是不能保证的,所以数组上的 for..in 可能会返回乱序的值。它还将列出所有属性,包括非数字属性(即不会通过迭代索引返回)和对象[[Prototype]]
链上的可枚举属性,因此您必须始终将其与 hasOwnProperty em> 测试你是否只想要自己的属性(最常见的情况)。
如果您使用的是 ES5 主机,那么您可以使用 Object.getOwnPropertyNames 和 Object.keys 之类的方法来获取自己的属性。但同样,订单无法保证。
最后,for、do 和 while 循环经过高度优化,性能差别很小,而且在一个浏览器中更快在另一个可能会很慢。仅在性能存在问题时才使用适合的并进行优化。
【讨论】:
以上是关于我应该为 JavaScript 数组和对象使用哪个 for 循环? [复制]的主要内容,如果未能解决你的问题,请参考以下文章