Mootools when using For(…in Array) problem

2019-02-24 12:41发布

问题:

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

回答1:

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.



回答2:

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



回答3:

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