0

I'd like to fire a function. Unfortunately I can't call it directly as the functions' name is provided as a string.

Example:

function myFunction() {
 alert('I am myFunction');
}
function anotherFunction() {
 alert('I am anotherFunction');
}
var func_name = 'myFunction';
$obj = jQuery('a');
$obj.each(function(){
 $(this).func_name(); // eval didn't help here :( 
});

Obviously this doesn't work, as JS expects func_name to be a valid function. Is there a way to have myFunction() fired instead of func_name()? Thanks.

UPDATE: Well, after testing some of the answers, it seems that my problem description isn't complete. :O I updated the code to include an object, which I want the function to be attached/run on.

Thanks again!

IAdapter
65.6k73 gold badges188 silver badges243 bronze badges
asked Sep 20, 2009 at 14:30
5

4 Answers 4

7

No reason to use eval. If your function is global, use window[func_name]()

With your updated question:

//the function $ returns an object, thus, this is changed
$(this).func_name();
//to this:
$(this)[func_name]();
answered Sep 20, 2009 at 14:41
Sign up to request clarification or add additional context in comments.

5 Comments

Indeed. But I'll leave my answer, anyway. Just for the case it's not global ;-)
Good answer. In JavaScript, most things you can do with a dot operator, you can also do with bracket notation. so a.foo() and a['foo']() do the same thing. Stay away from eval() whenever you can.
so, just to make sure I get this right. the 'a' is an object? and 'foo' is the functions name here? Then my current jQuery(this).eval(function_name+'()'); becomes jQuery(this)[function_name](); right?
actually I don't get it to work. Seems I'm missing something... but what? Greatly appreciated if someone might take a look at contactsheet.de/sandbox/autoload/index.html in comparison to contactsheet.de/sandbox/autoload/index2.html (where I'm trying to fire the same plugin with the discussed method - right after the alert). Thank you so much!
As far as I can tell the problem seems to be that you're not giving the function correct arguments. Otherwise it looks correct.
2

For methods, use

obj[func_name]()

Remember that globally declared functions are properties of the global object (ie window in browsers).

For local functions, as far as I know there's no way around

eval(func_name)()
answered Sep 20, 2009 at 14:52

2 Comments

For local, try this[func_name]();
this is not quite local, what he meant is (function(){ function A(){}; eval('A')(); })();
2

As other have mentioned, this is done with property accessor operators - "[" and "]". What matters in this case is how this function is declared and where it's being referenced from.

If it is declared globally (i.e. in the global scope, as function declaration or function expression), or assigned to a property of a Global Object at some point, then it is possible to access it as a property of a Global Object. In 3rd. edition of ECMAScript-262, one can access Global Object with an expression such as:

(function(){ return this; })();
// or just `this` when in global scope

(Note that in browsers, Global Object is usually the same object as the one referenced by global window, although it doesn't have to be that way).

So you would access global function as:

var globalObj = (function(){ return this; })();
globalObj['your_func'];
// or via `window`
window['your_func'];

The problem usually arises when function is declared locally – that is in another function body:

(function(){
 function your_func(){};
 // how to access `your_func` here?
});

The problem is essentially due to the fact that while it is possible to access Global Object (as in previous example), it's not possible to access function's Variable Object (i.e. object used as a "base" for variable and function declaration in function code).

You can certainly use eval in cases like that but it's most definitely a wrong approach to the problem. A much easier, more compatible and runtime-efficient way is to attach function as a property of some local object:

(function(){
 ...
 function your_func(){}
 var funcs = { your_func: your_func };
 ...
})();

then use the very same brackets to access a property – property referencing function in question:

funcs['your_func'];
answered Sep 20, 2009 at 15:19

Comments

0
eval(func_name + "()");

Eval will take a string and evaluate it at runtime.

answered Sep 20, 2009 at 14:38

1 Comment

Explanations needed for point deductions. This is a valid approach regardless of your personal opinions.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.