最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

prototypejs - How to exclude added to Array methods from processing in "for..in" loop? (javascript) - Stack Ov

programmeradmin8浏览0评论

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 ?

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 ?

Share Improve this question edited Dec 29, 2011 at 15:56 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Nov 27, 2009 at 15:59 zxcatzxcat 2,1143 gold badges26 silver badges41 bronze badges 1
  • 1 related, if not even duplicate: Javascript: hiding prototype methods in for loop?. See also this summing up answer – Bergi Commented Nov 9, 2012 at 13:25
Add a ment  | 

6 Answers 6

Reset to default 5

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.

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];
    }
};

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
});

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))
  {
    ...
  }
}

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 ment

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! :)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论