1

When iterating over a string or array (or anything else with a length property), I've always used a loop like this:

var foo = [...];
var i;
for(i=0; i<foo.length; i++) {
    // do something
}

However, I just encountered someone who did this:

var foo = [...];
var fooLen = foo.length;
var i;
for(i=0; i<fooLen; i++) {
    // do something
}

He said he thought the ".length" was recalculating the length, thus the loop would recalculate the length of the string/array over and over, so by saving its length to a variable it would be more optimized.

I always assumed length was just a value property because of the way it's used (it's not "asdf".length(), it's "asdf".length) but is this not the case?

Ricket
  • 33,368
  • 30
  • 112
  • 143
  • 3
    related info: http://stackoverflow.com/questions/5752906/is-reading-the-length-property-of-an-array-really-that-expensive-an-operation-i – user113716 Sep 15 '11 at 03:31
  • 1
    `for (var i=0, len=foo.length; i < len; i++){}` is, in my experience, a more common way of using this idea. It's neater and (I think) easier to read because it keeps the assignments within the for initialisation - of course this assumes the length of the array isn't needed prior to the start of the loop. A _lot_ of people do this routinely; a lot of people don't do it because they don't think about it; a much smaller group of people deliberately avoid this because they don't like to try to optimise prematurely or second-guess what the JS interpreter might optimise for you. – nnnnnn Sep 15 '11 at 03:40
  • As a side note, just because a property is not syntactically used as a function does not mean it isn't dynamic. The most infamous is `innerHtml` which is treated as a value but actually invokes the browser's HTML compiler when assigned to. – slebetman Sep 15 '11 at 03:47
  • 1
    @nnnnnn: another common one (and my favorite if order doesn't matter) is `for (var i=foo.length-1; i>=0; i--){}` – slebetman Sep 15 '11 at 03:49

4 Answers4

3

There are some situations where putting the length into a local variable is faster than accessing the .length property and it varies by browser. There have been performance discussions about this here on SO and numerous jsperf tests. In a modern browser, the differences were not as much as I thought they would be, but they do exist in some cases (I can't seem to find those previous threads).

There are also different types of objects that may have different performance characteristics. For example, a javascript array may have different performance characteristics than the array-like object returned from some DOM functions like getElementsByClassName().

And, there are some situations where you may be adding items to the end of the array and don't want to be iterating through the items you add so you get the length before you start.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

From MDC

for (var i = 0; i < a.length; i++) {  
    // Do something with a[i]  
}  

This is slightly inefficient as you are looking up the length property once every loop. An improvement is this:

for (var i = 0, len = a.length; i < len; i++) {  
    // Do something with a[i]  
} 
Bakudan
  • 19,134
  • 9
  • 53
  • 73
0

Maybe not much of a difference with "regular" arrays, but for something like "node.children.length" I would err on the safe side and call it only once. CoffeeScript does that for you automatically.

Note that there is an actual difference in behaviour if the length can change during the loop.

Thilo
  • 257,207
  • 101
  • 511
  • 656
0

It depends on if you are changing the foo's length.

var foo = [1,2,3];
  while(foo.length){
  foo.shift();
}

Obviously the code is keeping track of the foo's length, not simply remembering a value.

You can assign the length as a number in the loop.

for(i=0, L=foo.length;i<L; i++) {
    // do something to foo[i]
}
kennebec
  • 102,654
  • 32
  • 106
  • 127