views:

153

answers:

4

I'm using javascript to call functions that have been put into an object like so:

generatewidgets['mywidget'] = function (mystring) { code }

Later on, i loop through this object and call each function with a string parameter.

argument = 'abcdefg';
for (this.key in generatewidgets)
    generatewidgets[this.key](argument);

This works fine in IE8, but in firefox throws an error "argument is not a function". It does this with any variable name i specify for the string. I've also tried:

generatewidgets[this.key](argument+'');

which results in "'abcdefg' is not a function". Anyone know what this error means or why I'm getting it?

A: 

Drop the this.

for (var key in generatewidgets) {
  generatewidgets[key](argument);
}
Tim Down
A: 

It does work in Firefox 3.5 for me. This is how I tested:

>>> var generatewidgets = {}, argument = 'abcdefg';
>>> generatewidgets['mywidget'] = function(mystring) { console.log(mystring); }
function()
>>> for (this.key in generatewidgets) generatewidgets[this.key](argument);
abcdefg
Reinis I.
+1  A: 

You can also check the type before the call:

for (var key in generatewidgets) {
  if (typeof generatewidgets[key] === 'function')
    generatewidgets[key](argument);
}

This is probably a good idea anyway in case somewhere down the road you ever want to add a non-function item to the object.

Joel Coehoorn
This turned out to be the correct solution, although the reason why isn't clear from the post above so I'll specify more. I was creating generatewidgets = new Array(); rather than generatewidgets = {}; The array class creates an object with a bunch of non-function properties that were also appearing in the loop. The correct solution for me would be to instantiate the object correctly, although this solution probably works better in the more general case.
Travis
A: 

Enumerating over the properties of an object will enumerate over all properties of that object, including ones you didn't set yourself. This can be a problem with some JS libraries that set things on Object.prototype, because then enumerating the properties of your object will include those properties on the prototype.

I personally think the way that Object enumeration is designed in JavaScript is broken, but it's a bit too late to do anything about that.

Ted Mielczarek