views:

97

answers:

4

A clientside javascript library I've developed uses objects as hashes in some areas. It loops through objects parsed from Json data with a for...in loop using the property name as a key. eg... (pseudo code)

var conversations = {'sha1-string':{name:'foo',messages:[]}}
for(var id in conversations){
    console.log(id);
    console.log(conversations[id].name);
}

Unfortunately MooTools (and Prototype, etc) add methods to the global namespaces, so my for...in loops now iterate through MooTools' additions (eg. limit, round, times, each), causing errors when it applies logic to them as if it were the data expected.

As it's a library, I have to expect that it will be used with MooTools, Prototype, etc. Is there an easy way around this problem? My current solution is just to pass the object to a method which strips out the MooTools specific entries and returns the clean object, but this means also checking what Prototype and all similar libraries out there add, and seems to be a backwards way of doing things.

My other solution is to stop relying on the property name as a key, and perform validation in the loops to ensure I'm looking at the data I want to. Before I do that rewriting though, I'm wondering if anyone has a better/existing solution?

Thanks :)

+4  A: 

If your clientside objects are not inherited from other custom objects, you see if you could use the javascript's Object.hasOwnProperty method to find out if a certain property exists in the object itself and not up in the inheritance chain via the prototype object.

For browsers that don't support this method, you can write a wrapper around to check:

  var hasOwnProperty = function(object, property)   {
     if(object.hasOwnProperty)  {
        return object.hasOwnProperty(property);
     }
     var prop = object[property];
     return typeof(prop) !== "undefined" && prop !== 
             object.constructor.prototype[property];
  }

How to use it:

for(var key in someObj) {
  if(hasOwnProperty(someObj, key)) {
    // we are good to go!
  }
}
naikus
I don't think you'll find too many browsers without the `hasOwnProperty` method nowadays, on IE, it was introduced on IE5.5 (released on July 2000!)...
CMS
@CMS I always thought IE6 did not support it, thanks for pointing out
naikus
A: 

If I got it correctly, you are looking for the hasOwnProperty() method.

Álvaro G. Vicario
A: 

Using both MooTools and Prototype isn't a very good idea as they modify the base prototypes and can't co-exist peacefully. That said, none of them modify Object.prototype (not anymore) so you should not see any other properties besides your own.

Did you add a plugin which is perhaps adding these properties there? Could you give a more complete example that shows where these properties are getting listed and also the versions of these libraries that you are using?

hasOwnProperty checks will solve the prototype problem, but this shouldn't be needed in the first place, so maybe it's better to find out exactly which script is messing up.

MooTools has created a Hash type just because they didn't want to modify Object.prototype. Here's a quote from the docs:

Hash

A custom Object ({}) implementation which does not account for prototypes when setting, getting, or iterating. Useful because in JavaScript, we cannot use Object.prototype. Instead, we can use Hash.prototype!

Anurag
A: 

As "limit", "round", "times" and "each" are all additional methodes of the Array prototyp you're main failure is to use "for in" to iterate over arrays. You should check the type of the object before and use "for in" only for objects and "for" for arrays. Btw. "for in" is the slowest method to iterate over arrays.

eskimoblood
All these are additional methods on `Number`, not `Array`. I think we don't see the complete example here because enumerating a number is nowhere near what the OP has shown.
Anurag
Ok round and limit are from numer the others are from array. And its a bad idea to iterate over object I didn't know with "for in".
eskimoblood