Question

I've added some useful helpers to Array (such as toSource() for Opera). And now for..in returns the functions with normal properties.

I'm using for..in now, because the code is easier to read with it. And it's a native functional of js, so must be faster.

But adding type checks in loop makes it easier to use classic for(;;).

Is there any methods to avoid for..in enumerate functions ?

Cross-browser work is not very necessary (must work in Opera), but speed is important.

Thank you.


Edit:
Is there any ability to avoid for..in enumerate functions or custom properties from any Object ?

Was it helpful?

Solution

You should never use for..in loops to iterate over array elements. for..in is designed for iterating over properties, and should only be used for that, for exactly the reason you've just described. Many libraries modify array, date, etc prototypes, so you should not rely on for..in iterating just the array elements. Use the for(;;) method, it's guaranteed to do what you want. And it's no faster than a for..in loop, because it's native to javascript as well.

For more info, read about it in the prototype.js library.

OTHER TIPS

Yes, but it's JavaScript 1.7+ - only. Opera only has limited JavaScript 1.7 support, which includes very basic support of destructuring assignment so this won't work in Opera but it will work in Firefox.

This implementation allows safely using for [each](item in array):

Array.prototype.__iterator__ = function (flag) {
    var len = this.length, i = 0;

    for (; i < len; i++) {
        yield flag ? i : this[i];
    }
};

As others stated, you should NOT use for..in to iterate over arrays. It is slower than using a for(;;).

You should also cache the length of the array if you are concerned with performance, as:

for (var i=0, len=arr.length; i<len; i++) 
{
  ... 
}

Use only for..in to iterate over properties of objects. To exclude the inherited properties, use the hasOwnProperty() method:

for (var prop in object)
{
  // Don't include properties inherited from the prototype chain
  if (object.hasOwnProperty(prop))
  {
    ...
  }
}

There is another option now with ES5 support, it lets you define non-enumerable properties! It should be possible (though I haven't tested) to do something like this:

Object.defineProperty( Array.prototype, "myNewMethod", {
   value: function(){},
   writable: true,
   enumerable: false, /* this controls for..in visibility */
   configurable: true
});

What you're describing is exactly why you use

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

instead of:

for (var item in arr) { ... }

because they are different.

If you don't want all the members that you'll get in the second form and just the indexed elements then use the first form.

Edit: corrected wrong typeof usage thanks to @Bergi 's comment

good point about performance when iterating over (very) sparse arrays - I'd suggest that perhaps using isNaN(parseInt()) in the loop lets you find array elements only:

for( var propertyName in myArray){
    if( !isNaN(parseInt(propertyName)) ){ /* probably array element */ }
}

I don't know what performs better of hasOwnProperty() and the above approach though. You simply have to measure this with a very large array iterating it 10000 times or something like that. If you do some performance measurements, the results would be interesting so please share! :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top