JavaScript Loops: for…in vs for

I faced a strange behaviour in Javascript. I get

"Object doesn't support this property or method"

exception for the removeAttribute function in the following code:

var buttons = controlDiv.getElementsByTagName("button");
for ( var button in buttons )

When I change the code with the following, the problem disappears:

var buttons = controlDiv.getElementsByTagName("button");
for ( var i = 0; i < buttons.length; i++ )

What is the value of button inside the



Don't use for Array iteration.

It's important to understand that Javascript Array's square bracket syntax ([]) for accessing indicies is actually inherited from the Object...

obj.prop === obj['prop']  // true

The structure does not work like a more traditional for..each/in that would be found in other languages (php, python, etc...).

Javascript's is designed to iterate over the properties of an object. Producing the key of each property. Using this key combined with the Object's bracket syntax, you can easily access the values you are after.

var obj = {
    foo: "bar",
    fizz: "buzz",
    moo: "muck"

for ( var prop in obj ) {
    console.log(prop);      // foo / fizz / moo
    console.log(obj[prop]); // bar / buzz / muck

And because the Array is simply an Object with sequential numeric property names (indexes) the works in a similar way, producing the numeric indicies just as it produces the property names above.

An important characteristic of the structure is that it continues to search for enumerable properties up the prototype chain. It will also iterate inherited enumerable properties. It is up to you to verify that the current property exists directly on the local object and not the prototype it is attached to with hasOwnProperty()...

for ( var prop in obj ) {
    if ( obj.hasOwnProperty(prop) ) {
        // prop is actually obj's property (not inherited)

(More on Prototypal Inheritance)

The problem with using the structure on the Array type is that there is no garauntee as to what order the properties are produced... and generally speaking that is a farily important feature in processing an array.

Another problem is that it usually slower than a standard for implementation.

Bottom Line

Using a to iterate arrays is like using the butt of a screw driver to drive a nail... why wouldn't you just use a hammer (for)?

Answer is to be used when you want to loop over the properties of an object. But it works the same as a normal for loop: The loop variable contains the current "index", meaning the property of the object and not the value.

To iterate over arrays, you should use a normal for loop. buttons is not an array but a NodeList (an array like structure).

If iterate over buttons with with:

for(var i in a) {

You will see that it output something like:


because length and item are two properties of an object of type NodeList. So if you'd naively use, you would try to access buttons['length'].removeAttribute() which will throw an error as buttons['length'] is a function and not a DOM element.

So the correct way is to use a normal for loop. But there is another issue:

NodeLists are live, meaning whenever you access e.g. length, the list is updated (the elements are searched again). Therefore you should avoid unnecessary calls to length.


for(var i = 0, l = buttons.length; i < l, i++)

for(var key in obj) { } iterates over all elements in the object, including those of its prototypes. So if you are using it and cannot know nothing extended Object.prototype you should always test obj.hasOwnProperty(key) and skip the key if this check returns false.

for(start; continuation; loop) is a C-style loop: start is executed before the loop, continuation is tested and the loop only continues while it's true, loop is executed after every loop.


While should not generally be used for Arrays, however prior to ES5 there was a case for using it with sparse arrays.

As noted in other answers, the primary issues with and Arrays are:

  1. The properties are not necessarily returned in order (i.e. not 0, 1, 2 etc.)
  2. All enumerable properties are returned, including the non–index properties and those on the [[Prototype]] chain. This leads to lower performance as a hasOwnProperty test is probably required to avoid inherited properties.

One reason to use prior to ES5 was to improve performance with sparse arrays, provided order doesn't matter. For example, in the following:

var a = [0];
a[1000] = 1;

Iterating over a using will be much faster than using a for loop, as it will only visit two properties whereas a for loop will try 1001.

However, this case is made redundant by ES5's forEach, which only visits members that exist, so:


will also only iterate over two properties, in order.


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.