Get loop counter/index using for…of syntax in JavaScript

hobbes3 picture hobbes3 · Apr 16, 2012 · Viewed 505.2k times · Source

Caution:

question still applies to for…of loops.> Don't use for…in to iterate over an Array, use it to iterate over the properties of an object. That said, this


I understand that the basic for…in syntax in JavaScript looks like this:

for (var obj in myArray) {
    // ...
}

But how do I get the loop counter/index?

I know I could probably do something like:

var i = 0;
for (var obj in myArray) {
    alert(i)
    i++
}

Or even the good old:

for (var i = 0; i < myArray.length; i++) {
    var obj = myArray[i]
    alert(i)
}

But I would rather use the simpler for-in loop. I think they look better and make more sense.

Is there a simpler or more elegant way?


In Python it's easy:

for i, obj in enumerate(myArray):
    print i

Answer

Ry- picture Ry- · Apr 16, 2012

for…in iterates over property names, not values, and does so in an unspecified order (yes, even after ES6). You shouldn’t use it to iterate over arrays. For them, there’s ES5’s forEach method that passes both the value and the index to the function you give it:

var myArray = [123, 15, 187, 32];

myArray.forEach(function (value, i) {
    console.log('%d: %s', i, value);
});

// Outputs:
// 0: 123
// 1: 15
// 2: 187
// 3: 32

Or ES6’s Array.prototype.entries, which now has support across current browser versions:

for (const [i, value] of myArray.entries()) {
    console.log('%d: %s', i, value);
}

For iterables in general (where you would use a for…of loop rather than a for…in), there’s nothing built-in, however:

function* enumerate(iterable) {
    let i = 0;

    for (const x of iterable) {
        yield [i, x];
        i++;
    }
}

for (const [i, obj] of enumerate(myArray)) {
    console.log(i, obj);
}

demo

If you actually did mean for…in – enumerating properties – you would need an additional counter. Object.keys(obj).forEach could work, but it only includes own properties; for…in includes enumerable properties anywhere on the prototype chain.