在JavaScript中执行循环的最佳方法是什么?

时间:2008-10-11 01:21:18

标签: javascript jquery loops macros

我偶然发现了几种在JavaScript中循环的方法,我最喜欢的是:

for(var i = 0; i < a.length; i++){
    var element = a[i];
}

但是在这里进行测试(http://www.robertnyman.com/2008/04/11/javascript-loop-performance/)时,应该编写它以使长度仅计算一次。

在jQuery中有一个.each,你可以坚持一个功能。我喜欢这个更好一点,因为我不需要输入两次数组,就像上面的解决方案一样。

如果JavaScript支持宏,那么滚动你自己就是小菜一碟,但遗憾的是它没有。

那你们用什么?

9 个答案:

答案 0 :(得分:36)

我已经开始使用相关的迭代器了。性能是合理的,但更重要的是它允许您封装循环逻辑:

function createIterator(x) {
    var i = 0;

     return function(){
       return x[i++];
    };
}

然后使用:

var iterator=createIterator(['a','b','c','d','e','f','g']);

iterator();

返回“a”;

iterator();

返回“b”;

等等。

迭代整个列表并显示每个项目:

var current;

while(current=iterator())
{
    console.log(current);
}

请注意,上述内容仅适用于迭代包含“非虚假”值的列表。如果此数组包含以下任何一个:

  • 0
  • “”
  • 的NaN

前一个循环将停在那个项目上,而不是你想要/期望的那个。

为避免这种用途:

var current;

while((current=iterator())!==undefined)
{
   console.log(current);
}

答案 1 :(得分:10)

原始的小改进,只计算一次数组大小:

for(var i = 0, len = a.length; i < len; i++){ var element = a[i]; }

另外,我看到很多for..in循环。虽然请记住,它在技术上并不是犹太洁食,并且会特别引起Prototype的问题:

for (i in a) { var element = a[i]; }

答案 2 :(得分:6)

首先将长度存储在变量中。

  var len = a.length;
  for (var i = 0; i < len; i++) {
    var element = a[i];
  }

答案 3 :(得分:6)

我知道我迟到了,但是我使用反向循环来进行不依赖于顺序的循环。

与@Mr非常相似。麝香鼠 - 但简化了测试:

var i = a.length, element = null;
while (i--) {
  element = a[i];
}

答案 4 :(得分:2)

您可以随时使用while循环,并预先计算数组限制。

Var max = a.length-1;
var i = 0;

while(i <= max)
{
var element = a[i];
i++;
}

答案 5 :(得分:1)

如果数组中有许多元素且速度是个问题,那么你想使用一个从最高到最低迭代的while循环。

  var i = a.length;
  while( --i >= 0 ) {
    var element = a[i];
    // do stuff with element
  }  

答案 6 :(得分:1)

我自己不使用它,但我的一位同事使用这种风格:

var myArray = [1,2,3,4];
for (var i = 0, item; item = myArray[i]; ++i) {
    alert(item);
}
像Ash的回答一样,如果你的数组中有“假”值,这将会遇到问题。要避免该问题,请将其更改为(item = myArray[i]) != undefined

答案 7 :(得分:0)

我没有看到使用(;;)循环标准的问题是什么。 一点点测试

var x;
var a = [];
// filling array
var t0 = new Date().getTime();
for( var i = 0; i < 100000; i++ ) {
    a[i] = Math.floor( Math.random()*100000 );
}

// normal loop
var t1 = new Date().getTime();
for( var i = 0; i < 100000; i++ ) {
    x = a[i];
}

// using length
var t2 = new Date().getTime();
for( var i = 0; i < a.length; i++ ) {
    x = a[i];
}

// storing length (pollution - we now have a global l as well as an i )
var t3 = new Date().getTime();
for( var i = 0, l = a.length; i < l; i++ ) {
    x = a[i];
}

// for in
var t4 = new Date().getTime();
for( var i in a ) {
    x = a[i];
}

// checked for in
var t5 = new Date().getTime();
for( var i in a ) {
    if (a.hasOwnProperty(i)) {
        x = a[i];
    }
}

var t6 = new Date().getTime();
var msg = 'filling array: '+(t1-t0)+'ms\n'+
          'normal loop: '+(t2-t1)+'ms\n'+
          'using length: '+(t3-t2)+'ms\n'+
          'storing length: '+(t4-t3)+'ms\n'+
          'for in: '+(t5-t4)+'ms\n'+
          'checked for in: '+(t6-t5)+'ms';
console.log( msg );

结果:

filling array: 227ms
normal loop: 21ms
using length: 26ms
storing length: 24ms 
for in: 154ms
checked for in: 176ms

所以: - 对于in的花费最长,使用length属性(这是一个属性并且不需要计算)几乎与首先存储它一样快 - 这只比使用整数慢一些。 和AND()是循环数组的常用方法,每个人都期望和理解。

所有这些都为它们运行的​​范围添加了一个变量 - i - 这是此用途的通用名称,所以不应该用于其他事情。首先存储长度会向范围添加另一个var - l - 这是不必要的

答案 8 :(得分:-2)

所以,首先你确定完美的javascript循环,我相信它应该是这样的:

ary.each(function(){$ arguments [0])。remove();})

这可能需要prototype.js库。

接下来,您将获得对参数[0]部分的反对意见,并从您的服务器框架自动生成代码。这只适用于梯子是海边的情况。

现在,您已通过以下方式生成以上内容:

ary do:[:each |每个元素删除]。

这完成了语法完成并完全转换为上面的javascript。而且,在阅读你的代码之前,它会使人们的头部旋转之前没有使用过seasides原型集成。它确实让你感觉很酷。更不用说你可以到这里获得极客。女孩们喜欢它!