1

It's just that. I've looked online and I've looked on StackOverflow and I don't see anyone talking about this.

Is it normal when an array is constructed such as:

_e = Array();
_e[0] = 'admin_adv_from_date_month';
_e[1] = 'admin_adv_from_date_day';
_e[2] = 'admin_adv_from_date_year';
_e[3] = 'admin_adv_to_date_month';
_e[4] = 'admin_adv_to_date_day';
_e[5] = 'admin_adv_to_date_year';

That when you run through it like so:

enableElements : function(elements)
{
        for ( var e in elements )
        {
            hForm.enableElement(elements[e]);
        }
}

The last thing e is set to is 'hasObject' in my code. I had to implement a safe guard in 'enableElement', as e in this case returns null as 'hasObject' becomes a function:

enableElement : function(element)
    {
        var e = document.getElementById(element);
        if ( e )
        {
            e.disabled = false;
        }
    }

I'm running this on the latest Safari. Yes I know I could be using all sorts of alternative browsers that can do all sorts of whizbang stuff, but Safari is what I am using for this project.

Is this normal browser behavior? Why might this happen?

Asher
  • 291
  • 1
  • 3
  • 5
  • Ah yes, I must use the traditional for loop. Thanks for correcting me guys and setting me on the right track. Learned something today :-) – Asher Nov 25 '10 at 02:07
  • 1
    Just finished typing a short novel on that http://stackoverflow.com/questions/4261051/javascript-why-for-in-is-a-bad-practice/4273208#4273208 dont make me write another! :-) BTW, `_e = ['admin_adv_from_date_month','admin_adv_from_date_day','so on']` – Free Consulting Nov 25 '10 at 02:19

4 Answers4

4

https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

for...in

"Iterates a specified variable over all the properties of an object, in arbitrary order. For each distinct property, the specified statement is executed."

"Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea."

You should not use for...in to iterate over arrays, it's meant to iterate over object properties. Use a good old for (var i = 0; i < arr.length; i++) loop instead.

Community
  • 1
  • 1
deceze
  • 510,633
  • 85
  • 743
  • 889
2

You should not use for in to loop through an array.
Instead, use a normal for loop with an index.

To answer the question, for in will also enumerate all methods inherited from prototypes.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
2

Simple rule: don't use for...in to iterate an array, you're enumerating the array, and all the extra properties it may have. You should use a normal for loop here, like this:

enableElements : function(elements)
{
    for (var i=0; i<elements.length; i++)
    {
        hForm.enableElement(elements[i]);
    }
}
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
0

use .length, not for..in for arrays.

enableElements : function(elements) {
    for (var i=0, l = elements.length; i<l; i++)
    {
        hForm.enableElement(elements[i]);
    }

Otherwise you risk enumerating through anything extended through Object.prototype. You can .hasOwnProperty check but why do so when .length is perfect?

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434