Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to iterate over items in javascript?

I recently came accross a different way of looping though an array in Javascript.

I used to write loops something like this:

for (var len = 0; len < testData.length; len++) {
  total = total + testData[len];
}

I read some code that did it this way:

for (var len = 0; testData[len]; len++) {
  total = total + testData[len];
}

I was wondering how these would perform so I used jsPerf to find it out. The results are pretty amazing. I expected the second method to be a bit it faster than the first, but it's actually much, much faster.

Is there a down side I'm missing here? Or is this the best way to loop through the items of a list.

Update:

gray state is coming and Diode pointed me to a simple flaw in the testcase which made is seem to be faster.

After correcting the mistake, this is the fastest:

var datalen = testData.length;
for (var len = 0; len <datalen; len++) {
     total = total + testData[len];
}

Update 2:

After testing in some more browsers this testcase takes a different direction again. Only in Chrome and Opera the normal for loop is the fastest. In other all other browsers Shmiddty's way is just a bit faster.

var i = testData.length, sum=0;
while (i--){
    sum += testData[i];
}
like image 980
Sorskoot Avatar asked Sep 10 '12 18:09

Sorskoot


2 Answers

I'd argue that the first form is better. The second form has some issues. What if you have a sparse array that contains falsy values? Like: var testData = [ "text", undefined, false, 0, 5 ];

I also expect the first form to perform better. Especially if you 'cache' the value of testData.length Like so:

var i, len = testData.length;
for (i = 0; i < len; i += 1) {
  total = total + testData[i];
}
like image 101
Halcyon Avatar answered Nov 15 '22 18:11

Halcyon



UPDATE: I was wrong, forEach is very slow! It seems loops are better


You should use forEach, which is defined in ECMAScript 5th edition.

testData.forEach(function(val,i,arr){
    total += val;
});

The arguments are:

  • val is the current value
  • i is the current index
  • arr is the array

you don't have to use all of them:

testData.forEach(function(val){
    total += val;
});

And for the browsers that don't support it, this shim can be used:

if(!Array.prototype.forEach){
    Array.prototype.forEach = function(fn, scope) {
        for(var i = 0, len = this.length; i < len; ++i) {
            fn.call(scope || this, this[i], i, this);
        }
    }
}

See Array.forEach for more information.

like image 38
Oriol Avatar answered Nov 15 '22 18:11

Oriol