They really tried, but….

February 2nd, 2009 by Chouser

I'm sure they really tried, but they just plain screwed it up.

for( var i = 0; i < foo.length; ++i ) { ... }

That pattern is used very often in JavaScript to do something with each item in the array foo, setting aside for the moment that it's often not quite correct (if the var i is declared anywhere else in the same function).

You'd think they would have provided a more succinct way to walk
through an array. And actually they tried:

for( var i in foo ) { ... }

but they screwed it up, because in this case i is set not to each
value in foo, but to each index, 0 through whatever. ...as a string.

So the first time through, i is the string "0". Fortunately (I suppose) this still works as a parameter to your array, because you can say foo["0"] to get the initial item in the array.

But the knowledge of the amount of work being done to convert the integer range 0 through length into a series of strings, back to ints, and then look them up again in the array just pains me too much. It's not that the performance has actually ever hurt me in such cases, it's just that I can't stand to do it.

So I type for( var i = 0; i < foo.length; ++i ) one more time, and glance around to make sure i isn't being used for anything else nearby...

Tags:

5 Responses to “They really tried, but….”

  1. Kevin says:

    For what it’s worth, there is a new “for each…in” construct available in JavaScript 1.6 which is how “for…in” should have been in the first place:

    https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/for_each…in

    It was added by the E4X extensions to JavaScript so isn’t available everywhere yet. Sadly.

  2. Phil says:

    Kevin: unfortunately this is full of fail as well:

    > Warning: Never use a loop like this on arrays. Only use it on objects.

    Way to go guys. You had a chance to make it right, but you screwed up.

  3. Gabe says:

    You could just write an “each” helper method that takes an array and a closure (Array.each is even native in Firefox). It is a little syntactically noisy, but hey, this is Javascript we’re talking about :-)

    I use this all the time, and haven’t written a for loop in js for quite a while.

  4. travis says:

    in javascript the base type Object is used as the associative array or hash. for…in is used for looping through the properties of the object.

    JS’s Array is a subclass of Object, so you can iterate through the properties that way, but that’s really a bad way to do it. same goes for “for each…in” – it is also meant for Objects as hashes, but loops through the values instead.

    might want to make sure you know what you’re talking about before titling your post like that :)

    ooh, just noticed one other thing – either start with -1 or use i++ instead of ++i or else you’ll skip the first item every time (arrays are 0-indexed)

  5. Chouser says:

    > in javascript the base type Object is used as the
    > associative array or hash. for…in is used for looping
    > through the properties of the object.

    Yes, that is the underlying reason for the behavior I
    described, since properties are strings.

    > JS’s Array is a subclass of Object, so you can iterate
    > through the properties that way, but that’s really a bad way
    > to do it. same goes for “for each…in” – it is also meant for
    > Objects as hashes, but loops through the values instead.

    “for each…in” looks good. I’ll be happy to use it when
    supported by enough browsers.

    > might want to make sure you know what you’re talking about
    > before titling your post like that :)
    >
    > ooh, just noticed one other thing – either start with -1 or
    > use i++ instead of ++i or else you’ll skip the first item
    > every time (arrays are 0-indexed)

    Presumably you’re talking about my first example? The
    increment expression isn’t run until after the test anyway,
    so starting at 0 and using ++i or i++ is exactly correct.

    You might want to test your assertions before commenting.
    :-)

Leave a Reply