ray
ray

Reputation: 148

for..in loop over an Array iterates also over the prototype functions

I've got a serious bug, which I've never seen before. First of all I've a simple Array:

var myArray = ["123", "456", "789"]

Now I want to iterate over this Array with a for..in - loop:

function mapData(list) {
for ( var i in list) {
    var item = list[i];
    if (item) {
      // do something
    }
  }
}

After calling the method with mapData(myArray), firebug shows in the debugger this:

  1. Loop: i = 0; item = 123;
  2. Loop: i = 1; item = 456;
  3. Loop: i = 2; item = 789;
  4. Loop: i = compare;
  5. Loop: i = union;
  6. Loop: i = remove;
  7. Loop: i = select;
  8. Loop: i = contains;

So I think that are the prototype functions. But why? Any Ideas?

As I mentioned, I've never seen this before...

Upvotes: 0

Views: 62

Answers (2)

Denys Séguret
Denys Séguret

Reputation: 382274

That's not a bug, you're just iterating over all enumerable array properties, and a library you use added functions to Array.prototype like this :

Array.prototype.union = function(...)

The library can be fixed by making the functions not enumerable by setting them using defineProperty :

Object.defineProperty(Array.prototype, 'union', {value:function(){...}});

But you should never use for..in to iterate over an array.

Iterate like this :

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

or like this:

for (let item of list) {

Upvotes: 1

Explosion Pills
Explosion Pills

Reputation: 191779

Do not use for..in to iterate over Array. This will iterate over all enumerable properties of the Array object and may not iterate over them in order. There are two alternatives:

  • Array.forEach (not supported by IE8-, although there is probably a shim).
  • A simple for loop

Upvotes: 4

Related Questions