4

This problem been there for couple years.

I am writing some plugins for a Forum engine called Discuz, I use a lot of Mootools for my own projects. When I plug Mootools into this forum Engine(discuz) things went crazy...

After I did some debugging last year, I found that the problem is that Mootools prototype a lot of core elements, including Array, And, on the other hand, this forum engine uses a lof of For(i in Array) Loop for 'array'. Which will certainly cause problem because

for(i in [1,2,3,4,5]) console.log(i);  //0,1,2,3,4 the keys in this array 

**WITH MOOTOOLS
for(i in [1,2,3,4,5]) console.log(i);
//OUTPUT 0,1,2,3,4,$family,$constructor,pop,push,reverse,shift,sort,splice.......

Last time i use a parser to change all for(i in array) loop to add an 'if item.hasOwnProperty()' to by pass those prototypes But i think this is a very bad work-around cause u know, cause more problems...new versions, bug up their codes...etc

I wonder if there is work around to slove this problem? without touching any of this forum engine's js code, and also use Mootools?

I know that using For(..in ) for Array is bad, but my question is i dont want to touch this forum engine's javascript codes, i just want a solution to over load the problem

samfriend
  • 183
  • 1
  • 1
  • 6
  • I just wanted to make sure you know that the `for-in` statement is highly discouraged to **iterate** over array objects, its purpose is to **enumerate** object properties, if you use simple sequential loops, you will have less problems (they are also faster than `for-in`). See also: http://stackoverflow.com/questions/500504/javascript-for-in-with-arrays http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript/ – Christian C. Salvadó Aug 12 '11 at 01:58
  • possible duplicate of [Javascript prototype For...in Iterators?](http://stackoverflow.com/questions/7036097/javascript-prototype-for-in-iterators) – Dimitar Christoff Aug 12 '11 at 08:34

3 Answers3

2

You should use hasOwnProperty() as you mentioned. I'm not sure why you think this would cause more problems, indeed with a for(x in y) loop I'd be inclined to use hasOwnProperty() by default and only omit it for special cases.

Having said that, I wouldn't use a for(x in y) loop on an array. It's generally better to use a standard for(i=0; i<y.length; i++) loop which will of course ignore all the non-numeric properties. (Except perhaps if you know you've got non-consecutive array indexes, in which case for(x in y) will skip the unused indexes, but even in that case I'd probably still use a standard for and test for undefined within the loop.)

UPDATE: OK, I get it now. Your work-around to insert the hasOwnProperty() is the best solution I can think of if you want to keep using MooTools. Should be reasonably safe to insert it just after the closing ) of the for: you shouldn't need to check for existing {} brackets or add your own.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
0

Some newer browsers support ways to make all those extra properties (family, constructor, etc) be not enumerable, so they don't appear in the for-in loops.

However, if you want to be able to support the old browsers as well I think you are out of luck: for-in is hardwired syntax so you wont be able to monkey-patch it. (Anyway, the magic find-replace seems to have worked...)

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • `object.hasOwnProperty(propertyString)` is quite well-supported, and can be used to avoid issues with `for .. in` loops. – Delan Azabani Aug 12 '11 at 01:58
0

Mootools extends Array.prototype and maybe even Object.prototype, which can interfere with for .. in loops, which enumerate all properties, even those that exist in the object because they appear upwards on the prototype chain. Therefore, test if the property is a direct property of the object before using it:

for(i in a)
    if (a.hasOwnProperty(i))
        console.log(i);
Delan Azabani
  • 79,602
  • 28
  • 170
  • 210
  • The OP already does that. He just doesn't like having to modify the code since it comes from another library. – hugomg Aug 12 '11 at 02:05